owasp-depscan 5.0.2__tar.gz → 5.0.3__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-5.0.2/owasp_depscan.egg-info → owasp-depscan-5.0.3}/PKG-INFO +11 -6
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/README.md +9 -4
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/cli.py +42 -15
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/analysis.py +9 -3
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/audit.py +3 -1
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/csaf.py +20 -7
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/normalize.py +4 -4
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3/owasp_depscan.egg-info}/PKG-INFO +11 -6
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/owasp_depscan.egg-info/requires.txt +1 -1
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/pyproject.toml +2 -2
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_csaf.py +255 -484
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/LICENSE +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/MANIFEST.in +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/__init__.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/__init__.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/bom.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/config.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/explainer.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/github.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/license.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/logger.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/pkg_query.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/depscan/lib/utils.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/owasp_depscan.egg-info/SOURCES.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/owasp_depscan.egg-info/dependency_links.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/owasp_depscan.egg-info/entry_points.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/owasp_depscan.egg-info/top_level.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/setup.cfg +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_analysis.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_bom.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_explainer.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_github.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_license.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_norm.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_pkg_query.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/test/test_utils.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/__init__.py +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_data/fields.yml +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_data/meta.yml +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_data/rules.yml +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/0bsd.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/apache-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/artistic-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/bsl-1.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cc0-1.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cecill-2.1.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cern-ohl-p-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cern-ohl-s-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/cern-ohl-w-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/ecl-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/epl-1.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/epl-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/gfdl-1.3.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/gpl-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/gpl-3.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/isc.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/mit-0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/mit.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/ncsa.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/odbl-1.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/ofl-1.1.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/osl-3.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/postgresql.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/unlicense.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/upl-1.0.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/vim.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/choosealicense.com/_licenses/zlib.txt +0 -0
- {owasp-depscan-5.0.2 → owasp-depscan-5.0.3}/vendor/spdx/json/licenses.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: owasp-depscan
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.3
|
|
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: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Utilities
|
|
|
20
20
|
Requires-Python: >=3.8
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: appthreat-vulnerability-db>=5.5.
|
|
23
|
+
Requires-Dist: appthreat-vulnerability-db>=5.5.5
|
|
24
24
|
Requires-Dist: defusedxml
|
|
25
25
|
Requires-Dist: oras
|
|
26
26
|
Requires-Dist: PyYAML
|
|
@@ -147,22 +147,26 @@ Use the `/scan` endpoint to perform scans.
|
|
|
147
147
|
> [!NOTE]
|
|
148
148
|
> The `type` parameter is mandatory in server mode.
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
- Scanning a local directory.
|
|
151
|
+
|
|
151
152
|
```bash
|
|
152
153
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
- Scanning a SBOM file (present locally).
|
|
157
|
+
|
|
156
158
|
```bash
|
|
157
159
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
|
|
158
160
|
```
|
|
159
161
|
|
|
160
|
-
|
|
162
|
+
- Scanning a GitHub repo.
|
|
163
|
+
|
|
161
164
|
```bash
|
|
162
165
|
curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
|
|
163
166
|
```
|
|
164
167
|
|
|
165
|
-
|
|
168
|
+
- Uploading a SBOM file and generating results based on it.
|
|
169
|
+
|
|
166
170
|
```bash
|
|
167
171
|
curl -X POST -H 'Content-Type: multipart/form-data' -F 'file=@/tmp/app/sbom_file.json' http://0.0.0.0:7070/scan?type=js
|
|
168
172
|
```
|
|
@@ -242,6 +246,7 @@ options:
|
|
|
242
246
|
--explain Makes depscan to explain the various analysis. Useful for creating detailed reports.
|
|
243
247
|
--reachables-slices-file REACHABLES_SLICES_FILE
|
|
244
248
|
Path for the reachables slices file created by atom.
|
|
249
|
+
--purl SEARCH_PURL Scan a single package url.
|
|
245
250
|
-v, --version Display the version
|
|
246
251
|
```
|
|
247
252
|
|
|
@@ -108,22 +108,26 @@ Use the `/scan` endpoint to perform scans.
|
|
|
108
108
|
> [!NOTE]
|
|
109
109
|
> The `type` parameter is mandatory in server mode.
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
- Scanning a local directory.
|
|
112
|
+
|
|
112
113
|
```bash
|
|
113
114
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
|
|
114
115
|
```
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
- Scanning a SBOM file (present locally).
|
|
118
|
+
|
|
117
119
|
```bash
|
|
118
120
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
|
|
119
121
|
```
|
|
120
122
|
|
|
121
|
-
|
|
123
|
+
- Scanning a GitHub repo.
|
|
124
|
+
|
|
122
125
|
```bash
|
|
123
126
|
curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
|
|
124
127
|
```
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
- Uploading a SBOM file and generating results based on it.
|
|
130
|
+
|
|
127
131
|
```bash
|
|
128
132
|
curl -X POST -H 'Content-Type: multipart/form-data' -F 'file=@/tmp/app/sbom_file.json' http://0.0.0.0:7070/scan?type=js
|
|
129
133
|
```
|
|
@@ -203,6 +207,7 @@ options:
|
|
|
203
207
|
--explain Makes depscan to explain the various analysis. Useful for creating detailed reports.
|
|
204
208
|
--reachables-slices-file REACHABLES_SLICES_FILE
|
|
205
209
|
Path for the reachables slices file created by atom.
|
|
210
|
+
--purl SEARCH_PURL Scan a single package url.
|
|
206
211
|
-v, --version Display the version
|
|
207
212
|
```
|
|
208
213
|
|
|
@@ -298,6 +298,11 @@ def build_args():
|
|
|
298
298
|
dest="reachables_slices_file",
|
|
299
299
|
help="Path for the reachables slices file created by atom.",
|
|
300
300
|
)
|
|
301
|
+
parser.add_argument(
|
|
302
|
+
"--purl",
|
|
303
|
+
dest="search_purl",
|
|
304
|
+
help="Scan a single package url.",
|
|
305
|
+
)
|
|
301
306
|
parser.add_argument(
|
|
302
307
|
"-v",
|
|
303
308
|
"--version",
|
|
@@ -448,7 +453,7 @@ def summarise(
|
|
|
448
453
|
reached_purls=reached_purls,
|
|
449
454
|
)
|
|
450
455
|
pkg_vulnerabilities, pkg_group_rows = prepare_vdr(options)
|
|
451
|
-
vdr_file = bom_file.replace(".json", ".vdr.json")
|
|
456
|
+
vdr_file = bom_file.replace(".json", ".vdr.json") if bom_file else None
|
|
452
457
|
if pkg_vulnerabilities and bom_file:
|
|
453
458
|
try:
|
|
454
459
|
with open(bom_file, encoding="utf-8") as fp:
|
|
@@ -508,9 +513,15 @@ def download_rafs_based_image():
|
|
|
508
513
|
target=vdb_rafs_database_url, outdir=rafs_data_dir.name
|
|
509
514
|
)
|
|
510
515
|
|
|
511
|
-
if
|
|
512
|
-
|
|
513
|
-
|
|
516
|
+
if (
|
|
517
|
+
paths_list
|
|
518
|
+
and os.path.exists(
|
|
519
|
+
os.path.join(rafs_data_dir.name, "data.rafs")
|
|
520
|
+
)
|
|
521
|
+
and os.path.exists(
|
|
522
|
+
os.path.join(rafs_data_dir.name, "meta.rafs")
|
|
523
|
+
)
|
|
524
|
+
):
|
|
514
525
|
nydus_download_command = [
|
|
515
526
|
f"{nydus_image_command}",
|
|
516
527
|
"unpack",
|
|
@@ -540,7 +551,8 @@ def download_rafs_based_image():
|
|
|
540
551
|
|
|
541
552
|
except Exception:
|
|
542
553
|
LOG.info(
|
|
543
|
-
"Unable to pull the vulnerability database (rafs image) from %s. Trying to pull the non-rafs-based VDB image.",
|
|
554
|
+
"Unable to pull the vulnerability database (rafs image) from %s. Trying to pull the non-rafs-based VDB image.",
|
|
555
|
+
vdb_rafs_database_url,
|
|
544
556
|
)
|
|
545
557
|
rafs_image_downloaded = False
|
|
546
558
|
|
|
@@ -819,6 +831,12 @@ def main():
|
|
|
819
831
|
# Detect the project types and perform the right type of scan
|
|
820
832
|
if args.project_type:
|
|
821
833
|
project_types_list = args.project_type.split(",")
|
|
834
|
+
elif args.search_purl:
|
|
835
|
+
purl_obj = parse_purl(args.search_purl)
|
|
836
|
+
purl_obj["purl"] = args.search_purl
|
|
837
|
+
purl_obj["vendor"] = purl_obj.get("namespace")
|
|
838
|
+
project_types_list = [purl_obj.get("type")]
|
|
839
|
+
pkg_list = [purl_obj]
|
|
822
840
|
elif args.bom and not args.project_type:
|
|
823
841
|
project_types_list = ["bom"]
|
|
824
842
|
elif not args.non_universal_scan:
|
|
@@ -857,7 +875,12 @@ def main():
|
|
|
857
875
|
risk_report_file = areport_file.replace(
|
|
858
876
|
".json", f"-risk.{project_type}.json"
|
|
859
877
|
)
|
|
860
|
-
|
|
878
|
+
# Are we scanning a single purl
|
|
879
|
+
if args.search_purl:
|
|
880
|
+
bom_file = None
|
|
881
|
+
creation_status = True
|
|
882
|
+
# Are we scanning a bom file
|
|
883
|
+
elif args.bom and os.path.exists(args.bom):
|
|
861
884
|
bom_file = args.bom
|
|
862
885
|
creation_status = True
|
|
863
886
|
else:
|
|
@@ -876,14 +899,15 @@ def main():
|
|
|
876
899
|
if not creation_status:
|
|
877
900
|
LOG.debug("Bom file %s was not created successfully", bom_file)
|
|
878
901
|
continue
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
902
|
+
if bom_file:
|
|
903
|
+
LOG.debug("Scanning using the bom file %s", bom_file)
|
|
904
|
+
if not args.bom:
|
|
905
|
+
LOG.info(
|
|
906
|
+
"To improve performance, cache the bom file and invoke "
|
|
907
|
+
"depscan with --bom %s instead of -i",
|
|
908
|
+
bom_file,
|
|
909
|
+
)
|
|
910
|
+
pkg_list = get_pkg_list(bom_file)
|
|
887
911
|
if not pkg_list:
|
|
888
912
|
LOG.debug("No packages found in the project!")
|
|
889
913
|
continue
|
|
@@ -1097,7 +1121,10 @@ def main():
|
|
|
1097
1121
|
result_file=os.path.join(reports_dir, args.report_name),
|
|
1098
1122
|
)
|
|
1099
1123
|
elif args.report_template:
|
|
1100
|
-
LOG.warning(
|
|
1124
|
+
LOG.warning(
|
|
1125
|
+
"Template file %s doesn't exist, custom report not created.",
|
|
1126
|
+
args.report_template,
|
|
1127
|
+
)
|
|
1101
1128
|
# Submit vdr/vex files to threatdb server
|
|
1102
1129
|
if args.threatdb_server and (args.threatdb_username or args.threatdb_token):
|
|
1103
1130
|
submit_bom(
|
|
@@ -11,7 +11,7 @@ from rich.style import Style
|
|
|
11
11
|
from rich.table import Table
|
|
12
12
|
from rich.tree import Tree
|
|
13
13
|
from vdb.lib import CPE_FULL_REGEX
|
|
14
|
-
from vdb.lib.config import placeholder_fix_version
|
|
14
|
+
from vdb.lib.config import placeholder_exclude_version, placeholder_fix_version
|
|
15
15
|
from vdb.lib.utils import parse_cpe, parse_purl
|
|
16
16
|
|
|
17
17
|
from depscan.lib import config
|
|
@@ -84,7 +84,7 @@ def retrieve_bom_dependency_tree(bom_file):
|
|
|
84
84
|
:return: Dependency tree as a list
|
|
85
85
|
"""
|
|
86
86
|
if not bom_file:
|
|
87
|
-
return []
|
|
87
|
+
return [], None
|
|
88
88
|
try:
|
|
89
89
|
with open(bom_file, encoding="utf-8") as bfp:
|
|
90
90
|
bom_data = json.load(bfp)
|
|
@@ -97,6 +97,8 @@ def retrieve_bom_dependency_tree(bom_file):
|
|
|
97
97
|
|
|
98
98
|
def retrieve_oci_properties(bom_data):
|
|
99
99
|
props = {}
|
|
100
|
+
if not bom_data:
|
|
101
|
+
return props
|
|
100
102
|
for p in bom_data.get("metadata", {}).get("properties", []):
|
|
101
103
|
if p.get("name", "").startswith("oci:image:"):
|
|
102
104
|
props[p.get("name")] = p.get("value")
|
|
@@ -1174,7 +1176,11 @@ def suggest_version(results, pkg_aliases=None, purl_aliases=None):
|
|
|
1174
1176
|
else:
|
|
1175
1177
|
full_pkg = pkg_aliases.get(full_pkg, full_pkg)
|
|
1176
1178
|
version_upgrades = pkg_fix_map.get(full_pkg, set())
|
|
1177
|
-
|
|
1179
|
+
if (
|
|
1180
|
+
fixed_location != placeholder_fix_version
|
|
1181
|
+
and fixed_location != placeholder_exclude_version
|
|
1182
|
+
):
|
|
1183
|
+
version_upgrades.add(fixed_location)
|
|
1178
1184
|
pkg_fix_map[full_pkg] = version_upgrades
|
|
1179
1185
|
for k, v in pkg_fix_map.items():
|
|
1180
1186
|
# Don't go near certain packages
|
|
@@ -4,14 +4,16 @@ from depscan.lib import config
|
|
|
4
4
|
from depscan.lib.pkg_query import npm_metadata, pypi_metadata
|
|
5
5
|
|
|
6
6
|
# Dict mapping project type to the audit source
|
|
7
|
-
type_audit_map = {"nodejs": NpmSource(), "js": NpmSource()}
|
|
7
|
+
type_audit_map = {"nodejs": NpmSource(), "js": NpmSource(), "npm": NpmSource()}
|
|
8
8
|
|
|
9
9
|
# Dict mapping project type to risk audit
|
|
10
10
|
risk_audit_map = {
|
|
11
|
+
"npm": npm_metadata,
|
|
11
12
|
"nodejs": npm_metadata,
|
|
12
13
|
"js": npm_metadata,
|
|
13
14
|
"python": pypi_metadata,
|
|
14
15
|
"py": pypi_metadata,
|
|
16
|
+
"pypi": pypi_metadata,
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
|
|
@@ -1173,7 +1173,11 @@ class CsafOccurence:
|
|
|
1173
1173
|
)
|
|
1174
1174
|
self.references = res["related_urls"]
|
|
1175
1175
|
self.type = (res["type"],)
|
|
1176
|
-
self.severity =
|
|
1176
|
+
self.severity = (
|
|
1177
|
+
res["severity"] if (
|
|
1178
|
+
res["severity"] in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "NONE"]) else (
|
|
1179
|
+
"UNKNOWN")
|
|
1180
|
+
)
|
|
1177
1181
|
self.orig_date = res["source_orig_time"] or None
|
|
1178
1182
|
self.update_date = res["source_update_time"] or None
|
|
1179
1183
|
|
|
@@ -1186,7 +1190,8 @@ class CsafOccurence:
|
|
|
1186
1190
|
vuln["product_status"] = self.product_status
|
|
1187
1191
|
[ids, vuln["references"]] = format_references(self.references)
|
|
1188
1192
|
vuln["ids"] = ids
|
|
1189
|
-
|
|
1193
|
+
if self.cvss_v3:
|
|
1194
|
+
vuln["scores"] = [{"cvss_v3": self.cvss_v3, "products": [self.pkg]}]
|
|
1190
1195
|
self.notes.append(
|
|
1191
1196
|
{
|
|
1192
1197
|
"category": "general",
|
|
@@ -1299,27 +1304,32 @@ def parse_cvss(res):
|
|
|
1299
1304
|
version is not 3.0 or 3.1, None is returned.
|
|
1300
1305
|
"""
|
|
1301
1306
|
|
|
1302
|
-
# baseScore, vectorString, and version are required
|
|
1307
|
+
# baseScore, baseSeverity, vectorString, and version are required
|
|
1303
1308
|
cvss_v3 = res.get("cvss_v3")
|
|
1304
1309
|
if (
|
|
1305
1310
|
not cvss_v3
|
|
1306
1311
|
or not (vector_string := cvss_v3.get("vector_string"))
|
|
1307
|
-
or not (version := re.findall(r"3.0|3.1",
|
|
1312
|
+
or not (version := re.findall(r"3.0|3.1",
|
|
1313
|
+
cvss_v3.get("vector_string", "")))
|
|
1308
1314
|
or not (base_score := cvss_v3.get("base_score"))
|
|
1315
|
+
or (severity := res.get("severity")) not in
|
|
1316
|
+
["CRITICAL", "HIGH", "MEDIUM", "LOW", "NONE"]
|
|
1309
1317
|
):
|
|
1310
1318
|
return None
|
|
1311
1319
|
version = version[0]
|
|
1312
|
-
|
|
1320
|
+
cvss_v3_data = {
|
|
1313
1321
|
"baseScore": base_score,
|
|
1322
|
+
"baseSeverity": severity,
|
|
1314
1323
|
"attackVector": cvss_v3.get("attack_vector"),
|
|
1315
1324
|
"privilegesRequired": cvss_v3.get("privileges_required"),
|
|
1316
1325
|
"userInteraction": cvss_v3.get("user_interaction"),
|
|
1317
1326
|
"scope": cvss_v3.get("scope"),
|
|
1318
|
-
"baseSeverity": res.get("severity"),
|
|
1319
1327
|
"version": version,
|
|
1320
1328
|
"vectorString": vector_string,
|
|
1321
1329
|
}
|
|
1322
1330
|
|
|
1331
|
+
return cvss_v3_data
|
|
1332
|
+
|
|
1323
1333
|
|
|
1324
1334
|
def format_references(ref):
|
|
1325
1335
|
"""
|
|
@@ -1567,6 +1577,7 @@ def parse_toml(metadata):
|
|
|
1567
1577
|
'current_release_date'.
|
|
1568
1578
|
"""
|
|
1569
1579
|
tracking = parse_revision_history(metadata.get("tracking"))
|
|
1580
|
+
# FIXME: Could this be simplified as list comprehension without append
|
|
1570
1581
|
refs = []
|
|
1571
1582
|
[refs.append(v) for v in metadata.get("reference")]
|
|
1572
1583
|
notes = []
|
|
@@ -1873,6 +1884,8 @@ def add_vulnerabilities(data, results, direct_purls, reached_purls):
|
|
|
1873
1884
|
"HIGH": 2,
|
|
1874
1885
|
"MEDIUM": 3,
|
|
1875
1886
|
"LOW": 4,
|
|
1887
|
+
"UNKNOWN": 5,
|
|
1888
|
+
"NONE": 6,
|
|
1876
1889
|
}
|
|
1877
1890
|
affected_regex = re.compile(
|
|
1878
1891
|
r"(?P<lmod>[>=]{1,2})(?P<lower>\w+(?:.\w+)?(?:.\w+)?)-(?P<umod>[<=]{"
|
|
@@ -1884,7 +1897,7 @@ def add_vulnerabilities(data, results, direct_purls, reached_purls):
|
|
|
1884
1897
|
for r in results:
|
|
1885
1898
|
c = CsafOccurence(r)
|
|
1886
1899
|
new_vuln = c.to_dict()
|
|
1887
|
-
agg_score.add(severity_ref.get(c.severity))
|
|
1900
|
+
agg_score.add(severity_ref.get(c.severity, 5))
|
|
1888
1901
|
if c.search_string:
|
|
1889
1902
|
found = reached_dict.get(c.search_string)
|
|
1890
1903
|
if not found:
|
|
@@ -54,10 +54,10 @@ def create_pkg_variations(pkg_dict):
|
|
|
54
54
|
if purl_obj:
|
|
55
55
|
pkg_type = purl_obj.get("type")
|
|
56
56
|
qualifiers = purl_obj.get("qualifiers", {})
|
|
57
|
-
if qualifiers.get("distro_name"):
|
|
57
|
+
if qualifiers and qualifiers.get("distro_name"):
|
|
58
58
|
os_distro_name = qualifiers.get("distro_name")
|
|
59
59
|
name_aliases.add(f"""{os_distro_name}/{name}""")
|
|
60
|
-
if qualifiers.get("distro"):
|
|
60
|
+
if qualifiers and qualifiers.get("distro"):
|
|
61
61
|
os_distro = qualifiers.get("distro")
|
|
62
62
|
name_aliases.add(f"""{os_distro}/{name}""")
|
|
63
63
|
# almalinux-9.2 becomes almalinux-9
|
|
@@ -70,6 +70,7 @@ def create_pkg_variations(pkg_dict):
|
|
|
70
70
|
if vendor:
|
|
71
71
|
vendor_aliases.add(vendor)
|
|
72
72
|
vendor_aliases.add(vendor.lower())
|
|
73
|
+
vendor_aliases.add(vendor.lstrip("@"))
|
|
73
74
|
if (
|
|
74
75
|
vendor.startswith("org.")
|
|
75
76
|
or vendor.startswith("io.")
|
|
@@ -94,7 +95,6 @@ def create_pkg_variations(pkg_dict):
|
|
|
94
95
|
vendor_aliases.add("golang")
|
|
95
96
|
if pkg_type not in config.OS_PKG_TYPES:
|
|
96
97
|
name_aliases.add("package_" + name)
|
|
97
|
-
vendor_aliases.add(pkg_type)
|
|
98
98
|
if purl.startswith("pkg:composer"):
|
|
99
99
|
vendor_aliases.add("get" + name)
|
|
100
100
|
vendor_aliases.add(name + "_project")
|
|
@@ -168,7 +168,7 @@ def create_pkg_variations(pkg_dict):
|
|
|
168
168
|
name_aliases.add(name + "-bin")
|
|
169
169
|
else:
|
|
170
170
|
# Filter vendor aliases that are also name aliases
|
|
171
|
-
vendor_aliases = [x for x in vendor_aliases if x not in name_aliases]
|
|
171
|
+
vendor_aliases = [x for x in vendor_aliases if x not in name_aliases or x == vendor]
|
|
172
172
|
if len(vendor_aliases) > 0:
|
|
173
173
|
for vvar in list(vendor_aliases):
|
|
174
174
|
for nvar in list(name_aliases):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: owasp-depscan
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.3
|
|
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: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Utilities
|
|
|
20
20
|
Requires-Python: >=3.8
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: appthreat-vulnerability-db>=5.5.
|
|
23
|
+
Requires-Dist: appthreat-vulnerability-db>=5.5.5
|
|
24
24
|
Requires-Dist: defusedxml
|
|
25
25
|
Requires-Dist: oras
|
|
26
26
|
Requires-Dist: PyYAML
|
|
@@ -147,22 +147,26 @@ Use the `/scan` endpoint to perform scans.
|
|
|
147
147
|
> [!NOTE]
|
|
148
148
|
> The `type` parameter is mandatory in server mode.
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
- Scanning a local directory.
|
|
151
|
+
|
|
151
152
|
```bash
|
|
152
153
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
|
|
153
154
|
```
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
- Scanning a SBOM file (present locally).
|
|
157
|
+
|
|
156
158
|
```bash
|
|
157
159
|
curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
|
|
158
160
|
```
|
|
159
161
|
|
|
160
|
-
|
|
162
|
+
- Scanning a GitHub repo.
|
|
163
|
+
|
|
161
164
|
```bash
|
|
162
165
|
curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
|
|
163
166
|
```
|
|
164
167
|
|
|
165
|
-
|
|
168
|
+
- Uploading a SBOM file and generating results based on it.
|
|
169
|
+
|
|
166
170
|
```bash
|
|
167
171
|
curl -X POST -H 'Content-Type: multipart/form-data' -F 'file=@/tmp/app/sbom_file.json' http://0.0.0.0:7070/scan?type=js
|
|
168
172
|
```
|
|
@@ -242,6 +246,7 @@ options:
|
|
|
242
246
|
--explain Makes depscan to explain the various analysis. Useful for creating detailed reports.
|
|
243
247
|
--reachables-slices-file REACHABLES_SLICES_FILE
|
|
244
248
|
Path for the reachables slices file created by atom.
|
|
249
|
+
--purl SEARCH_PURL Scan a single package url.
|
|
245
250
|
-v, --version Display the version
|
|
246
251
|
```
|
|
247
252
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "owasp-depscan"
|
|
3
|
-
version = "5.0.
|
|
3
|
+
version = "5.0.3"
|
|
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>=5.5.
|
|
9
|
+
"appthreat-vulnerability-db>=5.5.5",
|
|
10
10
|
"defusedxml",
|
|
11
11
|
"oras",
|
|
12
12
|
"PyYAML",
|