Skip to content

Commit 4fffe68

Browse files
authored
Create pipeline for symbol reachability (#2151)
Signed-off-by: ziad hany <ziadhany2016@gmail.com>
1 parent e2dab13 commit 4fffe68

12 files changed

Lines changed: 3000 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ run = "scancodeio:combined_run"
154154
analyze_docker_image = "scanpipe.pipelines.analyze_docker:Docker"
155155
analyze_root_filesystem_or_vm_image = "scanpipe.pipelines.analyze_root_filesystem:RootFS"
156156
analyze_windows_docker_image = "scanpipe.pipelines.analyze_docker_windows:DockerWindows"
157+
analyze_symbols_reachability = "scanpipe.pipelines.analyze_symbols_reachability:SymbolReachability"
157158
benchmark_purls = "scanpipe.pipelines.benchmark_purls:BenchmarkPurls"
158159
collect_strings_gettext = "scanpipe.pipelines.collect_strings_gettext:CollectStringsGettext"
159160
collect_symbols_ctags = "scanpipe.pipelines.collect_symbols_ctags:CollectSymbolsCtags"
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# http://nexb.com and https://github.com/aboutcode-org/scancode.io
4+
# The ScanCode.io software is licensed under the Apache License version 2.0.
5+
# Data generated with ScanCode.io is provided as-is without warranties.
6+
# ScanCode is a trademark of nexB Inc.
7+
#
8+
# You may not use this software except in compliance with the License.
9+
# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
10+
# Unless required by applicable law or agreed to in writing, software distributed
11+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
13+
# specific language governing permissions and limitations under the License.
14+
#
15+
# Data Generated with ScanCode.io is provided on an "AS IS" BASIS, WITHOUT WARRANTIES
16+
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
17+
# ScanCode.io should be considered or used as legal advice. Consult an Attorney
18+
# for any legal advice.
19+
#
20+
# ScanCode.io is a free software code scanning tool from nexB Inc. and others.
21+
# Visit https://github.com/aboutcode-org/scancode.io for support and download.
22+
23+
from scanpipe.pipelines import Pipeline
24+
from scanpipe.pipes import reachability
25+
from scanpipe.pipes.symbols import TS_QUERIES
26+
27+
28+
class SymbolReachability(Pipeline):
29+
"""
30+
Determine the reachability of vulnerabilities identified in the project.
31+
32+
Note: You must run `find_vulnerabilities` pipeline before running this pipeline.
33+
34+
For every patch the git repository is cloned and extract the vulnerable and fixed
35+
symbols from the patch commit. These symbols are then matched against
36+
the project's codebase resources to determine if the vulnerable code
37+
is actually present and reachable.
38+
39+
The analysis checks if vulnerable symbols are defined, imported, called,
40+
or exactly match a code within the project files. The results, including
41+
tool_details and a reachability status (yes, unknown, or no), are stored
42+
in the `extra_data` of the matching resources under the `symbols_reachability` key.
43+
44+
Finally, a summary report is generated for each vulnerability
45+
advisory and saved as a JSON output file.
46+
"""
47+
48+
download_inputs = False
49+
is_addon = True
50+
results_url = "/project/{slug}/resources/?extra_data=symbol_reachability"
51+
52+
@classmethod
53+
def steps(cls):
54+
return (
55+
cls.get_vulnerabilities_patches,
56+
cls.collect_resource_index,
57+
cls.collect_patch_symbols,
58+
cls.collect_and_match_resources,
59+
cls.generate_advisory_reachability_report,
60+
)
61+
62+
def get_vulnerabilities_patches(self):
63+
"""Get unique patch for all vulnerabilities."""
64+
self.patches = reachability.get_vulnerabilities_patches(
65+
package_vulnerabilities=self.project.package_vulnerabilities,
66+
dependency_vulnerabilities=self.project.dependency_vulnerabilities,
67+
)
68+
69+
def collect_resource_index(self):
70+
"""Collect resources symbols for each resource"""
71+
self.candidate_resources = self.project.codebaseresources.files().filter(
72+
is_binary=False,
73+
is_archive=False,
74+
is_media=False,
75+
programming_language__in=TS_QUERIES.keys(),
76+
)
77+
self.resource_indexes = reachability.collect_resource_index(
78+
candidate_resources=self.candidate_resources, logger=self.log
79+
)
80+
81+
def collect_patch_symbols(self):
82+
"""Collect patch symbols for all related commits."""
83+
self.patch_symbols = reachability.collect_patch_symbols(
84+
patches=self.patches, logger=self.log
85+
)
86+
87+
def collect_and_match_resources(self):
88+
"""Match resource symbols against patch symbols."""
89+
reachability.match_patches_to_resources(
90+
patches=self.patches,
91+
patch_symbols=self.patch_symbols,
92+
resource_indexes=self.resource_indexes,
93+
candidate_resources=self.candidate_resources,
94+
logger=self.log,
95+
)
96+
97+
def generate_advisory_reachability_report(self):
98+
"""Generate a reachability report summarizing status by advisory."""
99+
reachability.generate_advisory_reachability_report(
100+
project=self.project,
101+
patches=self.patches,
102+
candidate_resources=self.candidate_resources,
103+
)

0 commit comments

Comments
 (0)