owasp-depscan 6.0.0a3__tar.gz → 6.0.0b3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of owasp-depscan might be problematic. Click here for more details.
- {owasp_depscan-6.0.0a3/owasp_depscan.egg-info → owasp_depscan-6.0.0b3}/PKG-INFO +3 -2
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/cli.py +17 -6
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/bom.py +5 -1
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/explainer.py +34 -14
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3/owasp_depscan.egg-info}/PKG-INFO +3 -2
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/owasp_depscan.egg-info/entry_points.txt +0 -1
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/owasp_depscan.egg-info/requires.txt +2 -1
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/pyproject.toml +6 -7
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/spdx/json/licenses.json +815 -692
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/LICENSE +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/MANIFEST.in +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/README.md +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/__init__.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/cli_options.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/__init__.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/audit.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/config.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/github.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/license.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/logger.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/__init__.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/cargo_pkg.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/metadata.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/npm_pkg.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/pkg_query.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/package_query/pypi_pkg.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/tomlparse.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/depscan/lib/utils.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/owasp_depscan.egg-info/SOURCES.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/owasp_depscan.egg-info/dependency_links.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/owasp_depscan.egg-info/top_level.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/setup.cfg +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_bom.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_explainer.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_github.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_license.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_pkg_query.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/test/test_utils.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/__init__.py +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_data/fields.yml +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_data/meta.yml +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_data/rules.yml +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/0bsd.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/apache-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/artistic-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsd-2-clause-patent.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/bsl-1.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cc0-1.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cecill-2.1.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cern-ohl-p-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cern-ohl-s-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/cern-ohl-w-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/ecl-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/epl-1.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/epl-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/gfdl-1.3.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/gpl-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/gpl-3.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/isc.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/mit-0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/mit.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/ncsa.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/odbl-1.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/ofl-1.1.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/osl-3.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/postgresql.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/unlicense.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/upl-1.0.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/vim.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -0
- {owasp_depscan-6.0.0a3 → owasp_depscan-6.0.0b3}/vendor/choosealicense.com/_licenses/zlib.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: owasp-depscan
|
|
3
|
-
Version: 6.0.
|
|
3
|
+
Version: 6.0.0b3
|
|
4
4
|
Summary: Fully open-source security audit for project dependencies based on known vulnerabilities and advisories.
|
|
5
5
|
Author-email: Team AppThreat <cloud@appthreat.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Utilities
|
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: appthreat-vulnerability-db[oras]
|
|
23
|
+
Requires-Dist: appthreat-vulnerability-db[oras]>=6.4.3
|
|
24
24
|
Requires-Dist: custom-json-diff>=2.1.6
|
|
25
25
|
Requires-Dist: defusedxml>=0.7.1
|
|
26
26
|
Requires-Dist: PyYAML>=6.0.2
|
|
@@ -31,6 +31,7 @@ Requires-Dist: cvss>=3.4
|
|
|
31
31
|
Requires-Dist: tomli>=2.2.1; python_full_version <= "3.11"
|
|
32
32
|
Requires-Dist: ds-xbom-lib
|
|
33
33
|
Requires-Dist: ds-analysis-lib
|
|
34
|
+
Requires-Dist: ds-reporting-lib
|
|
34
35
|
Provides-Extra: dev
|
|
35
36
|
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
36
37
|
Requires-Dist: flake8>=7.1.2; extra == "dev"
|
|
@@ -54,6 +54,8 @@ from depscan.lib.config import (
|
|
|
54
54
|
from depscan.lib.license import build_license_data, bulk_lookup
|
|
55
55
|
from depscan.lib.logger import DEBUG, LOG, SPINNER, console, IS_CI
|
|
56
56
|
|
|
57
|
+
from reporting_lib.htmlgen import ReportGenerator
|
|
58
|
+
|
|
57
59
|
if sys.platform == "win32" and os.environ.get("PYTHONIOENCODING") is None:
|
|
58
60
|
sys.stdin.reconfigure(encoding="utf-8")
|
|
59
61
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
@@ -100,6 +102,7 @@ def vdr_analyze_summarize(
|
|
|
100
102
|
scoped_pkgs,
|
|
101
103
|
bom_file,
|
|
102
104
|
bom_dir,
|
|
105
|
+
reports_dir,
|
|
103
106
|
pkg_list,
|
|
104
107
|
reachability_analyzer,
|
|
105
108
|
reachability_options,
|
|
@@ -115,6 +118,7 @@ def vdr_analyze_summarize(
|
|
|
115
118
|
:param scoped_pkgs: Dict containing package scopes.
|
|
116
119
|
:param bom_file: Single BOM file.
|
|
117
120
|
:param bom_dir: Directory containining bom files.
|
|
121
|
+
:param reports_dir: Directory containining report files.
|
|
118
122
|
:param pkg_list: Direct list of packages when the bom file is empty.
|
|
119
123
|
:param reachability_analyzer: Reachability Analyzer specified.
|
|
120
124
|
:param reachability_options: Reachability Analyzer options.
|
|
@@ -165,7 +169,11 @@ def vdr_analyze_summarize(
|
|
|
165
169
|
)
|
|
166
170
|
ds_version = get_version()
|
|
167
171
|
vdr_result = VDRAnalyzer(vdr_options=options).process()
|
|
168
|
-
|
|
172
|
+
# Set vdr_file in report folder
|
|
173
|
+
vdr_file = (
|
|
174
|
+
os.path.join(reports_dir, os.path.basename(bom_file)) if bom_file else None
|
|
175
|
+
)
|
|
176
|
+
vdr_file = vdr_file.replace(".cdx.json", ".vdr.json") if vdr_file else None
|
|
169
177
|
if not vdr_file and bom_dir:
|
|
170
178
|
vdr_file = os.path.join(bom_dir, DEPSCAN_DEFAULT_VDR_FILE)
|
|
171
179
|
if vdr_result.success:
|
|
@@ -617,15 +625,11 @@ def run_depscan(args):
|
|
|
617
625
|
html_report_file = depscan_options.get(
|
|
618
626
|
"html_report_file", os.path.join(reports_dir, "depscan.html")
|
|
619
627
|
)
|
|
620
|
-
pdf_report_file = depscan_options.get(
|
|
621
|
-
"pdf_report_file", os.path.join(reports_dir, "depscan.pdf")
|
|
622
|
-
)
|
|
623
628
|
txt_report_file = depscan_options.get(
|
|
624
629
|
"txt_report_file", os.path.join(reports_dir, "depscan.txt")
|
|
625
630
|
)
|
|
626
631
|
run_config_file = os.path.join(reports_dir, "depscan.toml.sample")
|
|
627
632
|
depscan_options["html_report_file"] = html_report_file
|
|
628
|
-
depscan_options["pdf_report_file"] = pdf_report_file
|
|
629
633
|
depscan_options["txt_report_file"] = txt_report_file
|
|
630
634
|
# Create reports directory
|
|
631
635
|
if reports_dir and not os.path.exists(reports_dir):
|
|
@@ -934,6 +938,7 @@ def run_depscan(args):
|
|
|
934
938
|
scoped_pkgs=scoped_pkgs,
|
|
935
939
|
bom_file=bom_files[0] if len(bom_files) == 1 else None,
|
|
936
940
|
bom_dir=args.bom_dir,
|
|
941
|
+
reports_dir=args.reports_dir,
|
|
937
942
|
pkg_list=pkg_list,
|
|
938
943
|
reachability_analyzer=reachability_analyzer,
|
|
939
944
|
reachability_options=reachability_options,
|
|
@@ -975,7 +980,13 @@ def run_depscan(args):
|
|
|
975
980
|
theme=(MONOKAI if os.getenv("USE_DARK_THEME") else DEFAULT_TERMINAL_THEME),
|
|
976
981
|
)
|
|
977
982
|
console.save_text(txt_report_file, clear=False)
|
|
978
|
-
|
|
983
|
+
# Prettify the rich html report
|
|
984
|
+
html_report_generator = ReportGenerator(
|
|
985
|
+
input_rich_html_path=html_report_file,
|
|
986
|
+
report_output_path=html_report_file,
|
|
987
|
+
raw_content=False,
|
|
988
|
+
)
|
|
989
|
+
html_report_generator.parse_and_generate_report()
|
|
979
990
|
# This logic needs refactoring
|
|
980
991
|
# render report into template if wished
|
|
981
992
|
if args.report_template and os.path.isfile(args.report_template):
|
|
@@ -556,7 +556,11 @@ def annotate_vdr(vdr_file, txt_report_file):
|
|
|
556
556
|
return
|
|
557
557
|
vdr = json_load(vdr_file)
|
|
558
558
|
metadata = vdr.get("metadata", {})
|
|
559
|
-
|
|
559
|
+
# Some cyclonedx sbom don't containg tools.components
|
|
560
|
+
if "components" in metadata.get("tools"):
|
|
561
|
+
tools = metadata.get("tools", {}).get("components", {})
|
|
562
|
+
else:
|
|
563
|
+
tools = {}
|
|
560
564
|
with open(txt_report_file, errors="ignore", encoding="utf-8") as txt_fp:
|
|
561
565
|
report = txt_fp.read()
|
|
562
566
|
annotations = vdr.get("annotations", []) or []
|
|
@@ -47,9 +47,14 @@ def explain(project_type, src_dir, bom_dir, vdr_file, vdr_result, explanation_mo
|
|
|
47
47
|
rsection = Markdown("""## Service Endpoints
|
|
48
48
|
|
|
49
49
|
The following endpoints and code hotspots were identified by depscan. Verify that proper authentication and authorization mechanisms are in place to secure them.""")
|
|
50
|
-
|
|
50
|
+
any_endpoints_shown = False
|
|
51
51
|
for ospec in openapi_spec_files:
|
|
52
|
-
pattern_methods = print_endpoints(
|
|
52
|
+
pattern_methods = print_endpoints(
|
|
53
|
+
ospec, rsection if not any_endpoints_shown else None
|
|
54
|
+
)
|
|
55
|
+
if not any_endpoints_shown and pattern_methods:
|
|
56
|
+
any_endpoints_shown = True
|
|
57
|
+
|
|
53
58
|
# Return early for endpoints only explanations
|
|
54
59
|
if explanation_mode in ("Endpoints",):
|
|
55
60
|
return
|
|
@@ -109,7 +114,7 @@ def _track_usage_targets(usage_targets, usages_object):
|
|
|
109
114
|
usage_targets.add(f"{file}#{l}")
|
|
110
115
|
|
|
111
116
|
|
|
112
|
-
def print_endpoints(ospec):
|
|
117
|
+
def print_endpoints(ospec, header_section=None):
|
|
113
118
|
if not ospec:
|
|
114
119
|
return
|
|
115
120
|
paths = json_load(ospec).get("paths") or {}
|
|
@@ -151,6 +156,9 @@ def print_endpoints(ospec):
|
|
|
151
156
|
sorted_areas.sort()
|
|
152
157
|
rtable.add_row(k, ("\n".join(v)).upper(), "\n".join(sorted_areas))
|
|
153
158
|
if pattern_methods:
|
|
159
|
+
# Print the header section
|
|
160
|
+
if header_section:
|
|
161
|
+
console.print(header_section)
|
|
154
162
|
console.print()
|
|
155
163
|
console.print(rtable)
|
|
156
164
|
return pattern_methods
|
|
@@ -178,6 +186,7 @@ def explain_reachables(
|
|
|
178
186
|
reachable_explanations = 0
|
|
179
187
|
checked_flows = 0
|
|
180
188
|
has_crypto_flows = False
|
|
189
|
+
explained_ids = {}
|
|
181
190
|
purls_reachable_explanations = defaultdict(int)
|
|
182
191
|
source_reachable_explanations = defaultdict(int)
|
|
183
192
|
sink_reachable_explanations = defaultdict(int)
|
|
@@ -194,16 +203,9 @@ def explain_reachables(
|
|
|
194
203
|
or (not areach.get("purls") and not cpp_flow)
|
|
195
204
|
):
|
|
196
205
|
continue
|
|
197
|
-
# Focus only on the prioritized list if available
|
|
198
|
-
# if project_type in ("java",) and pkg_group_rows:
|
|
199
|
-
# is_prioritized = False
|
|
200
|
-
# for apurl in areach.get("purls"):
|
|
201
|
-
# if pkg_group_rows.get(apurl):
|
|
202
|
-
# is_prioritized = True
|
|
203
|
-
# if not is_prioritized:
|
|
204
|
-
# continue
|
|
205
206
|
(
|
|
206
207
|
flow_tree,
|
|
208
|
+
added_ids,
|
|
207
209
|
comment,
|
|
208
210
|
source_sink_desc,
|
|
209
211
|
source_code_str,
|
|
@@ -218,7 +220,13 @@ def explain_reachables(
|
|
|
218
220
|
project_type,
|
|
219
221
|
vdr_result,
|
|
220
222
|
)
|
|
221
|
-
if
|
|
223
|
+
# The goal is to reduce duplicate explanations by checking if a given flow is similar to one we have explained
|
|
224
|
+
# before. We do this by checking the node ids, source-sink explanations, purl tags and so on.
|
|
225
|
+
added_ids_str = "-".join(added_ids)
|
|
226
|
+
# Have we seen this sequence before?
|
|
227
|
+
if explained_ids.get(added_ids_str) or len(added_ids) < 4:
|
|
228
|
+
continue
|
|
229
|
+
if not source_sink_desc or not flow_tree or len(flow_tree.children) < 4:
|
|
222
230
|
continue
|
|
223
231
|
# In non-reachables mode, we are not interested in reachable flows.
|
|
224
232
|
if (
|
|
@@ -269,6 +277,7 @@ def explain_reachables(
|
|
|
269
277
|
header_shown = True
|
|
270
278
|
console.print()
|
|
271
279
|
console.print(rtable)
|
|
280
|
+
explained_ids[added_ids_str] = True
|
|
272
281
|
reachable_explanations += 1
|
|
273
282
|
if purls_str:
|
|
274
283
|
purls_reachable_explanations[purls_str] += 1
|
|
@@ -428,7 +437,7 @@ def filter_tags(tags):
|
|
|
428
437
|
|
|
429
438
|
|
|
430
439
|
def is_filterable_code(project_type, code):
|
|
431
|
-
if len(code) <
|
|
440
|
+
if len(code) < 3:
|
|
432
441
|
return True
|
|
433
442
|
for c in (
|
|
434
443
|
"console.log",
|
|
@@ -455,8 +464,16 @@ def flow_to_str(explanation_mode, flow, project_type):
|
|
|
455
464
|
and flow.get("lineNumber")
|
|
456
465
|
and not flow.get("parentFileName").startswith("unknown")
|
|
457
466
|
):
|
|
458
|
-
|
|
467
|
+
# strip common prefixes
|
|
468
|
+
name = flow.get('parentFileName', '')
|
|
469
|
+
for p in ('src/main/java/', 'src/main/scala/'):
|
|
470
|
+
name = name.removeprefix(p)
|
|
471
|
+
file_loc = f"{name}#{flow.get('lineNumber')} "
|
|
459
472
|
node_desc = flow.get("code").split("\n")[0]
|
|
473
|
+
if (len(node_desc) < 3 or node_desc.endswith("{")) and len(flow.get("code")) > 3:
|
|
474
|
+
node_desc = " ".join(flow.get("code", "").split())
|
|
475
|
+
if "(" in node_desc:
|
|
476
|
+
node_desc = node_desc.split("(")[0] + "() ..."
|
|
460
477
|
if node_desc.endswith("("):
|
|
461
478
|
node_desc = f":diamond_suit: {node_desc})"
|
|
462
479
|
elif node_desc.startswith("return "):
|
|
@@ -510,6 +527,7 @@ def explain_flows(explanation_mode, flows, purls, project_type, vdr_result):
|
|
|
510
527
|
if purls:
|
|
511
528
|
purls_str = "\n".join(purls)
|
|
512
529
|
comments.append(f"[info]Reachable Packages:[/info]\n{purls_str}")
|
|
530
|
+
added_ids = []
|
|
513
531
|
added_flows = []
|
|
514
532
|
added_node_desc = []
|
|
515
533
|
has_check_tag = False
|
|
@@ -547,6 +565,7 @@ def explain_flows(explanation_mode, flows, purls, project_type, vdr_result):
|
|
|
547
565
|
if flow_str in added_flows or node_desc in added_node_desc:
|
|
548
566
|
continue
|
|
549
567
|
added_flows.append(flow_str)
|
|
568
|
+
added_ids.append(str(aflow.get("id", "")))
|
|
550
569
|
added_node_desc.append(node_desc)
|
|
551
570
|
if not tree:
|
|
552
571
|
tree = Tree(flow_str)
|
|
@@ -561,6 +580,7 @@ def explain_flows(explanation_mode, flows, purls, project_type, vdr_result):
|
|
|
561
580
|
)
|
|
562
581
|
return (
|
|
563
582
|
tree,
|
|
583
|
+
added_ids,
|
|
564
584
|
"\n".join(comments),
|
|
565
585
|
source_sink_desc,
|
|
566
586
|
source_code_str,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: owasp-depscan
|
|
3
|
-
Version: 6.0.
|
|
3
|
+
Version: 6.0.0b3
|
|
4
4
|
Summary: Fully open-source security audit for project dependencies based on known vulnerabilities and advisories.
|
|
5
5
|
Author-email: Team AppThreat <cloud@appthreat.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Utilities
|
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: appthreat-vulnerability-db[oras]
|
|
23
|
+
Requires-Dist: appthreat-vulnerability-db[oras]>=6.4.3
|
|
24
24
|
Requires-Dist: custom-json-diff>=2.1.6
|
|
25
25
|
Requires-Dist: defusedxml>=0.7.1
|
|
26
26
|
Requires-Dist: PyYAML>=6.0.2
|
|
@@ -31,6 +31,7 @@ Requires-Dist: cvss>=3.4
|
|
|
31
31
|
Requires-Dist: tomli>=2.2.1; python_full_version <= "3.11"
|
|
32
32
|
Requires-Dist: ds-xbom-lib
|
|
33
33
|
Requires-Dist: ds-analysis-lib
|
|
34
|
+
Requires-Dist: ds-reporting-lib
|
|
34
35
|
Provides-Extra: dev
|
|
35
36
|
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
36
37
|
Requires-Dist: flake8>=7.1.2; extra == "dev"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
appthreat-vulnerability-db[oras]
|
|
1
|
+
appthreat-vulnerability-db[oras]>=6.4.3
|
|
2
2
|
custom-json-diff>=2.1.6
|
|
3
3
|
defusedxml>=0.7.1
|
|
4
4
|
PyYAML>=6.0.2
|
|
@@ -8,6 +8,7 @@ packageurl-python>=0.16.0
|
|
|
8
8
|
cvss>=3.4
|
|
9
9
|
ds-xbom-lib
|
|
10
10
|
ds-analysis-lib
|
|
11
|
+
ds-reporting-lib
|
|
11
12
|
|
|
12
13
|
[:python_full_version <= "3.11"]
|
|
13
14
|
tomli>=2.2.1
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "owasp-depscan"
|
|
3
|
-
version = "6.0.
|
|
3
|
+
version = "6.0.0b3"
|
|
4
4
|
description = "Fully open-source security audit for project dependencies based on known vulnerabilities and advisories."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Team AppThreat", email = "cloud@appthreat.com"},
|
|
7
7
|
]
|
|
8
8
|
dependencies = [
|
|
9
|
-
"appthreat-vulnerability-db[oras]",
|
|
9
|
+
"appthreat-vulnerability-db[oras]>=6.4.3",
|
|
10
10
|
"custom-json-diff>=2.1.6",
|
|
11
11
|
"defusedxml>=0.7.1",
|
|
12
12
|
"PyYAML>=6.0.2",
|
|
@@ -16,7 +16,8 @@ dependencies = [
|
|
|
16
16
|
"cvss>=3.4",
|
|
17
17
|
"tomli>=2.2.1; python_full_version <= '3.11'",
|
|
18
18
|
"ds-xbom-lib",
|
|
19
|
-
"ds-analysis-lib"
|
|
19
|
+
"ds-analysis-lib",
|
|
20
|
+
"ds-reporting-lib"
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
requires-python = ">=3.10"
|
|
@@ -42,7 +43,6 @@ Funding = "https://owasp.org/donate/?reponame=www-project-dep-scan&title=OWASP+d
|
|
|
42
43
|
|
|
43
44
|
[project.scripts]
|
|
44
45
|
depscan = "depscan.cli:main"
|
|
45
|
-
scan = "depscan.cli:main"
|
|
46
46
|
|
|
47
47
|
[project.optional-dependencies]
|
|
48
48
|
dev = [
|
|
@@ -83,10 +83,10 @@ select = "B,C,E,F,W,T4,B9"
|
|
|
83
83
|
line-length = 99
|
|
84
84
|
|
|
85
85
|
[tool.uv.sources]
|
|
86
|
-
blint = { git = "https://github.com/owasp-dep-scan/blint", rev = "
|
|
87
|
-
appthreat-vulnerability-db = { git = "https://github.com/AppThreat/vulnerability-db", rev = "dc48e670acec1a62f8f20d6d4714f0c7c1e1f578" }
|
|
86
|
+
blint = { git = "https://github.com/owasp-dep-scan/blint", rev = "a2ca09e6f1355e3e31147fbd40027edbf130bc40" }
|
|
88
87
|
ds-xbom-lib = { workspace = true }
|
|
89
88
|
ds-analysis-lib = { workspace = true }
|
|
89
|
+
ds-reporting-lib = { workspace = true }
|
|
90
90
|
|
|
91
91
|
[tool.uv.workspace]
|
|
92
92
|
members = ["packages/*"]
|
|
@@ -95,4 +95,3 @@ members = ["packages/*"]
|
|
|
95
95
|
dev = [
|
|
96
96
|
"ruff>=0.11.6",
|
|
97
97
|
]
|
|
98
|
-
|