owasp-depscan 6.0.0b3__py3-none-any.whl → 6.0.0b4__py3-none-any.whl
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.
- depscan/cli.py +19 -245
- depscan/cli_options.py +13 -0
- depscan/lib/explainer.py +11 -7
- depscan/lib/utils.py +3 -38
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/METADATA +13 -17
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/RECORD +13 -13
- vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt +1 -1
- vendor/choosealicense.com/_licenses/osl-3.0.txt +1 -1
- vendor/spdx/json/licenses.json +873 -712
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/WHEEL +0 -0
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/entry_points.txt +0 -0
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/licenses/LICENSE +0 -0
- {owasp_depscan-6.0.0b3.dist-info → owasp_depscan-6.0.0b4.dist-info}/top_level.txt +0 -0
depscan/cli.py
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
import contextlib
|
|
5
|
-
import json
|
|
6
5
|
import os
|
|
7
6
|
import sys
|
|
8
|
-
import tempfile
|
|
9
7
|
from typing import List
|
|
10
8
|
|
|
11
9
|
from analysis_lib import (
|
|
@@ -24,7 +22,7 @@ from analysis_lib.utils import (
|
|
|
24
22
|
)
|
|
25
23
|
from analysis_lib.vdr import VDRAnalyzer
|
|
26
24
|
from analysis_lib.reachability import get_reachability_impl
|
|
27
|
-
from custom_json_diff.lib.utils import
|
|
25
|
+
from custom_json_diff.lib.utils import json_load
|
|
28
26
|
from rich.panel import Panel
|
|
29
27
|
from rich.terminal_theme import DEFAULT_TERMINAL_THEME, MONOKAI
|
|
30
28
|
from vdb.lib import config
|
|
@@ -67,14 +65,11 @@ LOGO = """
|
|
|
67
65
|
|
|
|
68
66
|
"""
|
|
69
67
|
|
|
70
|
-
|
|
68
|
+
SERVER_LIB = None
|
|
71
69
|
try:
|
|
72
|
-
from
|
|
70
|
+
from server_lib import simple, ServerOptions
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
app.config.from_prefixed_env()
|
|
76
|
-
app.config["PROVIDE_AUTOMATIC_OPTIONS"] = True
|
|
77
|
-
QUART_AVAILABLE = True
|
|
72
|
+
SERVER_LIB = simple
|
|
78
73
|
except ImportError:
|
|
79
74
|
pass
|
|
80
75
|
|
|
@@ -239,237 +234,6 @@ def set_project_types(args, src_dir):
|
|
|
239
234
|
return pkg_list, project_types_list
|
|
240
235
|
|
|
241
236
|
|
|
242
|
-
if QUART_AVAILABLE:
|
|
243
|
-
|
|
244
|
-
@app.get("/")
|
|
245
|
-
async def index():
|
|
246
|
-
"""
|
|
247
|
-
|
|
248
|
-
:return: An empty dictionary
|
|
249
|
-
"""
|
|
250
|
-
return {}
|
|
251
|
-
|
|
252
|
-
@app.get("/download-vdb")
|
|
253
|
-
async def download_vdb():
|
|
254
|
-
"""
|
|
255
|
-
|
|
256
|
-
:return: a JSON response indicating the status of the caching operation.
|
|
257
|
-
"""
|
|
258
|
-
if db_lib.needs_update(days=0, hours=VDB_AGE_HOURS, default_status=False):
|
|
259
|
-
if not ORAS_AVAILABLE:
|
|
260
|
-
return {
|
|
261
|
-
"error": "true",
|
|
262
|
-
"message": "The oras package must be installed to automatically download the vulnerability database. Install depscan using `pip install owasp-depscan[all]` or use the official container image.",
|
|
263
|
-
}
|
|
264
|
-
if download_image(vdb_database_url, config.DATA_DIR):
|
|
265
|
-
return {
|
|
266
|
-
"error": "false",
|
|
267
|
-
"message": "vulnerability database downloaded successfully",
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
"error": "true",
|
|
271
|
-
"message": "vulnerability database did not get downloaded correctly. Check the server logs.",
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
"error": "false",
|
|
275
|
-
"message": "vulnerability database already exists",
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
@app.route("/scan", methods=["GET", "POST"])
|
|
279
|
-
async def run_scan():
|
|
280
|
-
"""
|
|
281
|
-
:return: A JSON response containing the SBOM file path and a list of
|
|
282
|
-
vulnerabilities found in the scanned packages
|
|
283
|
-
"""
|
|
284
|
-
q = request.args
|
|
285
|
-
params = await request.get_json()
|
|
286
|
-
uploaded_bom_file = await request.files
|
|
287
|
-
|
|
288
|
-
url = None
|
|
289
|
-
path = None
|
|
290
|
-
multi_project = None
|
|
291
|
-
project_type = None
|
|
292
|
-
results = []
|
|
293
|
-
profile = "generic"
|
|
294
|
-
deep = False
|
|
295
|
-
suggest_mode = True if q.get("suggest") in ("true", "1") else False
|
|
296
|
-
fuzzy_search = True if q.get("fuzzy_search") in ("true", "1") else False
|
|
297
|
-
if q.get("url"):
|
|
298
|
-
url = q.get("url")
|
|
299
|
-
if q.get("path"):
|
|
300
|
-
path = q.get("path")
|
|
301
|
-
if q.get("multiProject"):
|
|
302
|
-
multi_project = q.get("multiProject", "").lower() in ("true", "1")
|
|
303
|
-
if q.get("deep"):
|
|
304
|
-
deep = q.get("deep", "").lower() in ("true", "1")
|
|
305
|
-
if q.get("type"):
|
|
306
|
-
project_type = q.get("type")
|
|
307
|
-
if q.get("profile"):
|
|
308
|
-
profile = q.get("profile")
|
|
309
|
-
if params is not None:
|
|
310
|
-
if not url and params.get("url"):
|
|
311
|
-
url = params.get("url")
|
|
312
|
-
if not path and params.get("path"):
|
|
313
|
-
path = params.get("path")
|
|
314
|
-
if not multi_project and params.get("multiProject"):
|
|
315
|
-
multi_project = params.get("multiProject", "").lower() in (
|
|
316
|
-
"true",
|
|
317
|
-
"1",
|
|
318
|
-
)
|
|
319
|
-
if not deep and params.get("deep"):
|
|
320
|
-
deep = params.get("deep", "").lower() in (
|
|
321
|
-
"true",
|
|
322
|
-
"1",
|
|
323
|
-
)
|
|
324
|
-
if not project_type and params.get("type"):
|
|
325
|
-
project_type = params.get("type")
|
|
326
|
-
if not profile and params.get("profile"):
|
|
327
|
-
profile = params.get("profile")
|
|
328
|
-
|
|
329
|
-
if not path and not url and (uploaded_bom_file.get("file", None) is None):
|
|
330
|
-
return {
|
|
331
|
-
"error": "true",
|
|
332
|
-
"message": "path or url or a bom file upload is required",
|
|
333
|
-
}, 400
|
|
334
|
-
if not project_type:
|
|
335
|
-
return {"error": "true", "message": "project type is required"}, 400
|
|
336
|
-
if db_lib.needs_update(days=0, hours=VDB_AGE_HOURS, default_status=False):
|
|
337
|
-
return (
|
|
338
|
-
{
|
|
339
|
-
"error": "true",
|
|
340
|
-
"message": "Vulnerability database is empty. Prepare the "
|
|
341
|
-
"vulnerability database by invoking /download-vdb endpoint "
|
|
342
|
-
"before running scans.",
|
|
343
|
-
},
|
|
344
|
-
500,
|
|
345
|
-
{"Content-Type": "application/json"},
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
cdxgen_server = app.config.get("CDXGEN_SERVER_URL")
|
|
349
|
-
bom_file_path = None
|
|
350
|
-
|
|
351
|
-
if uploaded_bom_file.get("file", None) is not None:
|
|
352
|
-
bom_file = uploaded_bom_file["file"]
|
|
353
|
-
bom_file_content = bom_file.read().decode("utf-8")
|
|
354
|
-
try:
|
|
355
|
-
_ = json.loads(bom_file_content)
|
|
356
|
-
except Exception as e:
|
|
357
|
-
LOG.info(e)
|
|
358
|
-
return (
|
|
359
|
-
{
|
|
360
|
-
"error": "true",
|
|
361
|
-
"message": "The uploaded file must be a valid JSON or XML.",
|
|
362
|
-
},
|
|
363
|
-
400,
|
|
364
|
-
{"Content-Type": "application/json"},
|
|
365
|
-
)
|
|
366
|
-
|
|
367
|
-
LOG.debug("Processing uploaded file")
|
|
368
|
-
bom_file_suffix = str(bom_file.filename).rsplit(".", maxsplit=1)[-1]
|
|
369
|
-
tmp_bom_file = tempfile.NamedTemporaryFile(
|
|
370
|
-
delete=False, suffix=f".bom.{bom_file_suffix}"
|
|
371
|
-
)
|
|
372
|
-
path = tmp_bom_file.name
|
|
373
|
-
file_write(path, bom_file_content)
|
|
374
|
-
|
|
375
|
-
# Path points to a project directory
|
|
376
|
-
# Bug# 233. Path could be a url
|
|
377
|
-
if url or (path and os.path.isdir(path)):
|
|
378
|
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".bom.json") as bfp:
|
|
379
|
-
project_type_list = project_type.split(",")
|
|
380
|
-
bom_status = create_bom(
|
|
381
|
-
bfp.name,
|
|
382
|
-
path,
|
|
383
|
-
{
|
|
384
|
-
"url": url,
|
|
385
|
-
"path": path,
|
|
386
|
-
"project_type": project_type_list,
|
|
387
|
-
"multiProject": multi_project,
|
|
388
|
-
"cdxgen_server": cdxgen_server,
|
|
389
|
-
"profile": profile,
|
|
390
|
-
"deep": deep,
|
|
391
|
-
},
|
|
392
|
-
)
|
|
393
|
-
if bom_status:
|
|
394
|
-
LOG.debug("BOM file was generated successfully at %s", bfp.name)
|
|
395
|
-
bom_file_path = bfp.name
|
|
396
|
-
|
|
397
|
-
# Path points to a SBOM file
|
|
398
|
-
else:
|
|
399
|
-
if os.path.exists(path):
|
|
400
|
-
bom_file_path = path
|
|
401
|
-
# Direct purl-based lookups are not supported yet.
|
|
402
|
-
if bom_file_path is not None:
|
|
403
|
-
pkg_list, _ = get_pkg_list(bom_file_path)
|
|
404
|
-
# Here we are assuming there will be only one type
|
|
405
|
-
if project_type in type_audit_map:
|
|
406
|
-
audit_results = audit(project_type, pkg_list)
|
|
407
|
-
if audit_results:
|
|
408
|
-
results = results + audit_results
|
|
409
|
-
if not pkg_list:
|
|
410
|
-
LOG.debug("Empty package search attempted!")
|
|
411
|
-
else:
|
|
412
|
-
LOG.debug("Scanning %d oss dependencies for issues", len(pkg_list))
|
|
413
|
-
bom_data = json_load(bom_file_path)
|
|
414
|
-
if not bom_data:
|
|
415
|
-
return (
|
|
416
|
-
{
|
|
417
|
-
"error": "true",
|
|
418
|
-
"message": "Unable to generate SBOM. Check your input path or url.",
|
|
419
|
-
},
|
|
420
|
-
400,
|
|
421
|
-
{"Content-Type": "application/json"},
|
|
422
|
-
)
|
|
423
|
-
options = VdrAnalysisKV(
|
|
424
|
-
project_type,
|
|
425
|
-
results,
|
|
426
|
-
pkg_aliases={},
|
|
427
|
-
purl_aliases={},
|
|
428
|
-
suggest_mode=suggest_mode,
|
|
429
|
-
scoped_pkgs={},
|
|
430
|
-
no_vuln_table=True,
|
|
431
|
-
bom_file=bom_file_path,
|
|
432
|
-
pkg_list=[],
|
|
433
|
-
direct_purls={},
|
|
434
|
-
reached_purls={},
|
|
435
|
-
console=console,
|
|
436
|
-
logger=LOG,
|
|
437
|
-
fuzzy_search=fuzzy_search,
|
|
438
|
-
)
|
|
439
|
-
vdr_result = VDRAnalyzer(vdr_options=options).process()
|
|
440
|
-
if vdr_result.success:
|
|
441
|
-
pkg_vulnerabilities = vdr_result.pkg_vulnerabilities
|
|
442
|
-
if pkg_vulnerabilities:
|
|
443
|
-
bom_data["vulnerabilities"] = pkg_vulnerabilities
|
|
444
|
-
return json.dumps(bom_data), 200, {"Content-Type": "application/json"}
|
|
445
|
-
return (
|
|
446
|
-
{
|
|
447
|
-
"error": "true",
|
|
448
|
-
"message": "Unable to generate SBOM. Check your input path or url.",
|
|
449
|
-
},
|
|
450
|
-
500,
|
|
451
|
-
{"Content-Type": "application/json"},
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
def run_server(args):
|
|
455
|
-
"""
|
|
456
|
-
Run depscan as server
|
|
457
|
-
|
|
458
|
-
:param args: Command line arguments passed to the function.
|
|
459
|
-
"""
|
|
460
|
-
print(LOGO)
|
|
461
|
-
console.print(
|
|
462
|
-
f"Depscan server running on {args.server_host}:{args.server_port}"
|
|
463
|
-
)
|
|
464
|
-
app.config["CDXGEN_SERVER_URL"] = args.cdxgen_server
|
|
465
|
-
app.run(
|
|
466
|
-
host=args.server_host,
|
|
467
|
-
port=args.server_port,
|
|
468
|
-
debug=os.getenv("SCAN_DEBUG_MODE") == "debug",
|
|
469
|
-
use_reloader=False,
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
|
|
473
237
|
def run_depscan(args):
|
|
474
238
|
"""
|
|
475
239
|
Detects the project type, performs various scans and audits,
|
|
@@ -518,8 +282,20 @@ def run_depscan(args):
|
|
|
518
282
|
os.environ["CDXGEN_DEBUG_MODE"] = "debug"
|
|
519
283
|
LOG.setLevel(DEBUG)
|
|
520
284
|
if args.server_mode:
|
|
521
|
-
if
|
|
522
|
-
|
|
285
|
+
if SERVER_LIB:
|
|
286
|
+
server_options = ServerOptions(
|
|
287
|
+
server_host=args.server_host,
|
|
288
|
+
server_port=args.server_port,
|
|
289
|
+
cdxgen_server=args.cdxgen_server,
|
|
290
|
+
allowed_hosts=args.server_allowed_hosts,
|
|
291
|
+
allowed_paths=args.server_allowed_paths,
|
|
292
|
+
console=console,
|
|
293
|
+
logger=LOG,
|
|
294
|
+
debug=args.enable_debug or os.environ.get("SCAN_DEBUG_MODE") == "debug",
|
|
295
|
+
create_bom=create_bom,
|
|
296
|
+
max_content_length=os.getenv("DEPSCAN_SERVER_MAX_CONTENT_LENGTH"),
|
|
297
|
+
)
|
|
298
|
+
return simple.run_server(server_options)
|
|
523
299
|
else:
|
|
524
300
|
LOG.info(
|
|
525
301
|
"The required packages for server mode are unavailable. Reinstall depscan using `pip install owasp-depscan[all]`."
|
|
@@ -565,9 +341,7 @@ def run_depscan(args):
|
|
|
565
341
|
bom_dir_mode = args.bom_dir and os.path.exists(args.bom_dir)
|
|
566
342
|
# Are we running with a config file
|
|
567
343
|
config_file_mode = args.config and os.path.exists(args.config)
|
|
568
|
-
depscan_options = {**vars(args)}
|
|
569
|
-
depscan_options["src_dir"] = src_dir
|
|
570
|
-
depscan_options["reports_dir"] = reports_dir
|
|
344
|
+
depscan_options = {**vars(args), "src_dir": src_dir, "reports_dir": reports_dir}
|
|
571
345
|
# Is the user looking for semantic analysis?
|
|
572
346
|
# We can default to this when run against a BOM directory
|
|
573
347
|
if (
|
depscan/cli_options.py
CHANGED
|
@@ -245,6 +245,19 @@ def build_parser():
|
|
|
245
245
|
dest="server_port",
|
|
246
246
|
help="depscan server port",
|
|
247
247
|
)
|
|
248
|
+
parser.add_argument(
|
|
249
|
+
"--server-allowed-hosts",
|
|
250
|
+
nargs="*",
|
|
251
|
+
help="List of allowed hostnames or IPs that can access the server (e.g., 'localhost 192.168.1.10'). If unspecified, no host allowlist is enforced.",
|
|
252
|
+
default=None,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
parser.add_argument(
|
|
256
|
+
"--server-allowed-paths",
|
|
257
|
+
nargs="*",
|
|
258
|
+
help="List of allowed filesystem paths that can be scanned by the server. Restricts `path` parameter in /scan requests.",
|
|
259
|
+
default=None,
|
|
260
|
+
)
|
|
248
261
|
parser.add_argument(
|
|
249
262
|
"--cdxgen-server",
|
|
250
263
|
default=os.getenv("CDXGEN_SERVER_URL"),
|
depscan/lib/explainer.py
CHANGED
|
@@ -33,7 +33,7 @@ def explain(project_type, src_dir, bom_dir, vdr_file, vdr_result, explanation_mo
|
|
|
33
33
|
pattern_methods = {}
|
|
34
34
|
has_any_explanation = False
|
|
35
35
|
has_any_crypto_flows = False
|
|
36
|
-
slices_files = glob.glob(f"{bom_dir}/**/*reachables.slices
|
|
36
|
+
slices_files = glob.glob(f"{bom_dir}/**/*reachables.slices*.json", recursive=True)
|
|
37
37
|
openapi_spec_files = None
|
|
38
38
|
# Should we explain the endpoints and Code Hotspots
|
|
39
39
|
if explanation_mode in (
|
|
@@ -70,9 +70,10 @@ The following endpoints and code hotspots were identified by depscan. Verify tha
|
|
|
70
70
|
if "-" in fn:
|
|
71
71
|
section_label = f"# Explanations for {fn.split('-')[0].upper()}"
|
|
72
72
|
console.print(Markdown(section_label))
|
|
73
|
-
if
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
if reachables_data := json_load(sf, log=LOG):
|
|
74
|
+
# Backwards compatibility
|
|
75
|
+
if isinstance(reachables_data, dict) and reachables_data.get("reachables"):
|
|
76
|
+
reachables_data = reachables_data.get("reachables")
|
|
76
77
|
if explanation_mode in ("NonReachables",):
|
|
77
78
|
rsection = Markdown(
|
|
78
79
|
f"""## {section_title}
|
|
@@ -193,7 +194,10 @@ def explain_reachables(
|
|
|
193
194
|
has_explanation = False
|
|
194
195
|
header_shown = False
|
|
195
196
|
has_cpp_flow = False
|
|
196
|
-
|
|
197
|
+
# Backwards compatibility
|
|
198
|
+
if isinstance(reachables, dict) and reachables.get("reachables"):
|
|
199
|
+
reachables = reachables.get("reachables")
|
|
200
|
+
for areach in reachables:
|
|
197
201
|
cpp_flow = is_cpp_flow(areach.get("flows"))
|
|
198
202
|
if not has_cpp_flow and cpp_flow:
|
|
199
203
|
has_cpp_flow = True
|
|
@@ -465,8 +469,8 @@ def flow_to_str(explanation_mode, flow, project_type):
|
|
|
465
469
|
and not flow.get("parentFileName").startswith("unknown")
|
|
466
470
|
):
|
|
467
471
|
# strip common prefixes
|
|
468
|
-
name = flow.get(
|
|
469
|
-
for p in (
|
|
472
|
+
name = flow.get("parentFileName", "")
|
|
473
|
+
for p in ("src/main/java/", "src/main/scala/"):
|
|
470
474
|
name = name.removeprefix(p)
|
|
471
475
|
file_loc = f"{name}#{flow.get('lineNumber')} "
|
|
472
476
|
node_desc = flow.get("code").split("\n")[0]
|
depscan/lib/utils.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
-
import shutil
|
|
5
|
-
from datetime import datetime
|
|
6
4
|
|
|
7
5
|
from custom_json_diff.lib.utils import file_read, file_write, json_load
|
|
8
6
|
from jinja2 import Environment
|
|
@@ -84,11 +82,12 @@ def is_exe(src):
|
|
|
84
82
|
Detect if the source is a binary file
|
|
85
83
|
|
|
86
84
|
:param src: Source path
|
|
87
|
-
:return True if binary file. False otherwise.
|
|
85
|
+
:return: True if binary file. False otherwise.
|
|
88
86
|
"""
|
|
89
87
|
if os.path.isfile(src):
|
|
90
88
|
try:
|
|
91
|
-
|
|
89
|
+
with open(src, "rb") as f:
|
|
90
|
+
return is_binary_string(f.read(1024))
|
|
92
91
|
except Exception:
|
|
93
92
|
return False
|
|
94
93
|
return False
|
|
@@ -228,40 +227,6 @@ def get_all_imports(src_dir):
|
|
|
228
227
|
return import_list
|
|
229
228
|
|
|
230
229
|
|
|
231
|
-
def export_pdf(
|
|
232
|
-
html_file,
|
|
233
|
-
pdf_file,
|
|
234
|
-
title="DepScan Analysis",
|
|
235
|
-
footer=f"Report generated by OWASP dep-scan at {datetime.now().strftime('%B %d, %Y %H:%M')}",
|
|
236
|
-
):
|
|
237
|
-
"""
|
|
238
|
-
Method to export html as pdf using pdfkit
|
|
239
|
-
"""
|
|
240
|
-
pdf_options = {
|
|
241
|
-
"page-size": "A2",
|
|
242
|
-
"margin-top": "0.5in",
|
|
243
|
-
"margin-right": "0.25in",
|
|
244
|
-
"margin-bottom": "0.5in",
|
|
245
|
-
"margin-left": "0.25in",
|
|
246
|
-
"encoding": "UTF-8",
|
|
247
|
-
"outline": None,
|
|
248
|
-
"title": title,
|
|
249
|
-
"footer-right": footer,
|
|
250
|
-
"minimum-font-size": "12",
|
|
251
|
-
"disable-smart-shrinking": "",
|
|
252
|
-
}
|
|
253
|
-
if shutil.which("wkhtmltopdf"):
|
|
254
|
-
try:
|
|
255
|
-
import pdfkit
|
|
256
|
-
|
|
257
|
-
if not pdf_file and html_file:
|
|
258
|
-
pdf_file = html_file.replace(".html", ".pdf")
|
|
259
|
-
if os.path.exists(html_file):
|
|
260
|
-
pdfkit.from_file(html_file, pdf_file, options=pdf_options)
|
|
261
|
-
except Exception:
|
|
262
|
-
pass
|
|
263
|
-
|
|
264
|
-
|
|
265
230
|
def render_template_report(
|
|
266
231
|
vdr_file,
|
|
267
232
|
bom_file,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: owasp-depscan
|
|
3
|
-
Version: 6.0.
|
|
3
|
+
Version: 6.0.0b4
|
|
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]>=6.4.
|
|
23
|
+
Requires-Dist: appthreat-vulnerability-db[oras]>=6.4.4
|
|
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
|
|
@@ -33,24 +33,22 @@ Requires-Dist: ds-xbom-lib
|
|
|
33
33
|
Requires-Dist: ds-analysis-lib
|
|
34
34
|
Requires-Dist: ds-reporting-lib
|
|
35
35
|
Provides-Extra: dev
|
|
36
|
-
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
37
36
|
Requires-Dist: flake8>=7.1.2; extra == "dev"
|
|
38
37
|
Requires-Dist: pytest>=8.3.4; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-asyncio>=1.2.0; extra == "dev"
|
|
39
39
|
Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
|
|
40
40
|
Requires-Dist: httpretty>=1.1.4; extra == "dev"
|
|
41
41
|
Provides-Extra: server
|
|
42
|
-
Requires-Dist:
|
|
42
|
+
Requires-Dist: ds-server-lib; extra == "server"
|
|
43
43
|
Provides-Extra: ext
|
|
44
44
|
Requires-Dist: atom-tools>=0.7.8; extra == "ext"
|
|
45
|
-
Requires-Dist: blint>=
|
|
46
|
-
Requires-Dist: pdfkit>=1.0.0; extra == "ext"
|
|
45
|
+
Requires-Dist: blint>=3.0.5; extra == "ext"
|
|
47
46
|
Provides-Extra: perf
|
|
48
47
|
Requires-Dist: hishel[redis]>=0.1.1; extra == "perf"
|
|
49
48
|
Provides-Extra: all
|
|
50
49
|
Requires-Dist: atom-tools>=0.7.8; extra == "all"
|
|
51
|
-
Requires-Dist: blint>=
|
|
52
|
-
Requires-Dist:
|
|
53
|
-
Requires-Dist: pdfkit>=1.0.0; extra == "all"
|
|
50
|
+
Requires-Dist: blint>=3.0.5; extra == "all"
|
|
51
|
+
Requires-Dist: ds-server-lib; extra == "all"
|
|
54
52
|
Requires-Dist: PyGithub>=2.6.1; extra == "all"
|
|
55
53
|
Requires-Dist: hishel[redis]>=0.1.1; extra == "all"
|
|
56
54
|
Dynamic: license-file
|
|
@@ -59,7 +57,7 @@ Dynamic: license-file
|
|
|
59
57
|
|
|
60
58
|
OWASP dep-scan is a next-generation security and risk audit tool based on known vulnerabilities, advisories, and license limitations for project dependencies. Both local repositories and container images are supported as the input, and the tool is ideal for integration with ASPM/VM platforms and in CI environments.
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
<img src="depscan-logo.png" width="200" height="auto" />
|
|
63
61
|
|
|
64
62
|
[](https://github.com/owasp-dep-scan/dep-scan/actions/workflows/pythonpublish.yml)
|
|
65
63
|
|
|
@@ -235,6 +233,11 @@ options:
|
|
|
235
233
|
depscan server host
|
|
236
234
|
--server-port SERVER_PORT
|
|
237
235
|
depscan server port
|
|
236
|
+
--server-allowed-hosts [SERVER_ALLOWED_HOSTS ...]
|
|
237
|
+
List of allowed hostnames or IPs that can access the server (e.g., 'localhost 192.168.1.10'). If unspecified, no host allowlist is
|
|
238
|
+
enforced.
|
|
239
|
+
--server-allowed-paths [SERVER_ALLOWED_PATHS ...]
|
|
240
|
+
List of allowed filesystem paths that can be scanned by the server. Restricts `path` parameter in /scan requests.
|
|
238
241
|
--cdxgen-server CDXGEN_SERVER
|
|
239
242
|
cdxgen server url. Eg: http://cdxgen:9090
|
|
240
243
|
--debug Run depscan in debug mode.
|
|
@@ -317,13 +320,6 @@ docker compose up
|
|
|
317
320
|
depscan --server --server-host 0.0.0.0 --server-port 7070
|
|
318
321
|
```
|
|
319
322
|
|
|
320
|
-
In server mode, use the `/download-vdb` endpoint to cache the vulnerability database.
|
|
321
|
-
|
|
322
|
-
```bash
|
|
323
|
-
# This would take over 2 minutes
|
|
324
|
-
curl http://0.0.0.0:7070/download-vdb
|
|
325
|
-
```
|
|
326
|
-
|
|
327
323
|
Use the `/scan` endpoint to perform scans.
|
|
328
324
|
|
|
329
325
|
> [!NOTE]
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
depscan/__init__.py,sha256=u_HyD63vlgVi48bUU6bI8O1fdXJOLPaNwCrMJdCnzJE,165
|
|
2
|
-
depscan/cli.py,sha256=
|
|
3
|
-
depscan/cli_options.py,sha256=
|
|
2
|
+
depscan/cli.py,sha256=8_ekeym-3klttdXwTLqbiHiDV6vNtKQq8ww1MQMMFtE,32883
|
|
3
|
+
depscan/cli_options.py,sha256=gTlfwv9q66B25d5XTUPkIbh_bynQCXnR447hwMXDdr4,9968
|
|
4
4
|
depscan/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
depscan/lib/audit.py,sha256=i6sE-vN0Fk5gc-npHIhrrior4772_tTlPVAlznyuogo,1582
|
|
6
6
|
depscan/lib/bom.py,sha256=bByZcT8EFfO-GBOcSlsu43hZHw2-nnEOjC85cjIr1T8,20960
|
|
7
7
|
depscan/lib/config.py,sha256=v3Rv4nyPMjvk-EbpWSSYcloQa4v2N0bTzXKWF5nDJvg,9572
|
|
8
|
-
depscan/lib/explainer.py,sha256=
|
|
8
|
+
depscan/lib/explainer.py,sha256=7rNqEYfc6Ge2DNr2PQIwaZTY5yj0Q-SqmSYQHyhj0fs,22279
|
|
9
9
|
depscan/lib/github.py,sha256=h6e_12xLwspXJbt_7lW6vuHaqgJQgyFSRCLrfUndCH4,1697
|
|
10
10
|
depscan/lib/license.py,sha256=ChwqAXPrMcDQJqSgDag7Th8VwoRCq8oMvwPt64iL4gw,2404
|
|
11
11
|
depscan/lib/logger.py,sha256=gU5epbOHlhvuFhMqRTgn71AJ4KPB5Gf2iAmgTx3qI-4,2837
|
|
12
12
|
depscan/lib/tomlparse.py,sha256=q_JATqfqzv6_06wcSx0tRpcKY-x16NcNXxMnL5T1Mcw,5035
|
|
13
|
-
depscan/lib/utils.py,sha256=
|
|
13
|
+
depscan/lib/utils.py,sha256=6KSQxBHKTkVRBLfe0u8-FChQapwqu2KOk_Xeu0u1-hY,8443
|
|
14
14
|
depscan/lib/package_query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
depscan/lib/package_query/cargo_pkg.py,sha256=mlvTJP2LIBpGWEAX2aOmQImkTzn0Ih9zup6Lp7nI-dU,5108
|
|
16
16
|
depscan/lib/package_query/metadata.py,sha256=Nnh6ctLIXPRTMoHOjZC7uhmFM3ogGljg22dHkZZE62M,6617
|
|
17
17
|
depscan/lib/package_query/npm_pkg.py,sha256=eXdTeq1ffxLN3fWfMh3QcGG1u0VYLGR4-0BmVoD5BPk,15443
|
|
18
18
|
depscan/lib/package_query/pkg_query.py,sha256=ODnRegpD3gv5FIKy0ogXMEITcdfVVV-eoIaWf7UhrQU,7038
|
|
19
19
|
depscan/lib/package_query/pypi_pkg.py,sha256=scn6UhMWqA0ajS-u5UVMGV7Vx-6PEY75lN6uET9yU5c,4808
|
|
20
|
-
owasp_depscan-6.0.
|
|
20
|
+
owasp_depscan-6.0.0b4.dist-info/licenses/LICENSE,sha256=oQnCbnZtJ_NLDdOLc-rVY1D1N0RNWLHPpYXcc77xzSo,1073
|
|
21
21
|
vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
vendor/choosealicense.com/_data/fields.yml,sha256=ydNsITXFUuADzGPM-jcUcJnN0r_qSGgH51oV27nX3Qs,819
|
|
23
23
|
vendor/choosealicense.com/_data/meta.yml,sha256=rSNmnx0LE6VA9wnR29Y_P9s-TnADQqbdw2enE4i1mWM,1792
|
|
@@ -27,7 +27,7 @@ vendor/choosealicense.com/_licenses/afl-3.0.txt,sha256=geEcMDR01aeoPeGCdJ_JjZ4Mf
|
|
|
27
27
|
vendor/choosealicense.com/_licenses/agpl-3.0.txt,sha256=Kh_aeCNLcVAuLPgDUCG1WS9eun6BByKKyk2Vu6ZF45c,35944
|
|
28
28
|
vendor/choosealicense.com/_licenses/apache-2.0.txt,sha256=YJ4stZn4SqpB2O8p2P2wTRZPqyLo2Skso0pZnQ9Wozg,12624
|
|
29
29
|
vendor/choosealicense.com/_licenses/artistic-2.0.txt,sha256=Yv9JWPxIuOcT9VDW97f9iaOq9UuSWN9XPlM4k6iBiSE,9649
|
|
30
|
-
vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt,sha256=
|
|
30
|
+
vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt,sha256=3vGJfYTAVu_6smy6FlLBh2XTzYBDduBchLU8CgRj7Yw,2425
|
|
31
31
|
vendor/choosealicense.com/_licenses/bsd-2-clause-patent.txt,sha256=Nun0tMNvQE8EQ9OYuu4__J_oCv9PRefJH7TjCWWBZnk,3497
|
|
32
32
|
vendor/choosealicense.com/_licenses/bsd-2-clause.txt,sha256=2CN9FlwXZBaoq5OL9-Eg2PNFCYFj_OyQF8VlL0Z_7K8,2260
|
|
33
33
|
vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt,sha256=dCbal-fEXLo_-tWO4A3qAhDdvw3RFM1mU2UGuGaA4ug,2348
|
|
@@ -62,16 +62,16 @@ vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt,sha256=-URwwR8aEk_uTxhRMkHz
|
|
|
62
62
|
vendor/choosealicense.com/_licenses/ncsa.txt,sha256=TjJzqwphQaGAsPgU6vQmp_3zClN7X_kVxZ7ConaAIkI,2939
|
|
63
63
|
vendor/choosealicense.com/_licenses/odbl-1.0.txt,sha256=2zFarxYKYFBr5ztVazm1wDzrAE8JLs2ZM57qcWfDkzI,26179
|
|
64
64
|
vendor/choosealicense.com/_licenses/ofl-1.1.txt,sha256=rfABl7lxjv8qg1PN1kvFYFWF2xxTNugbGRd97vnFWMo,5824
|
|
65
|
-
vendor/choosealicense.com/_licenses/osl-3.0.txt,sha256=
|
|
65
|
+
vendor/choosealicense.com/_licenses/osl-3.0.txt,sha256=h9uUNnrydW8Szex8PzQ0dnbd2e4gTUe735gsfwIKwqM,11856
|
|
66
66
|
vendor/choosealicense.com/_licenses/postgresql.txt,sha256=LTaJOLi4f7dA3DRsx2t4F267JuOSvHzJz5SJ7Pdpn5U,1709
|
|
67
67
|
vendor/choosealicense.com/_licenses/unlicense.txt,sha256=3cLgcN8LslzpUbCVTZwbXSKxfxUNWOrGa9plPQRLte0,2001
|
|
68
68
|
vendor/choosealicense.com/_licenses/upl-1.0.txt,sha256=yJ3mfZkFmzSHesz6uOF9S0fX6hkCVMhr7rmgUdGL2vc,3253
|
|
69
69
|
vendor/choosealicense.com/_licenses/vim.txt,sha256=d5GQjXB328L8EBkhKgxcjk344D3K7UfcJmP1barrhHI,6119
|
|
70
70
|
vendor/choosealicense.com/_licenses/wtfpl.txt,sha256=BxXeubkvQm32MDmlZsBcbzJzBpR5kWgw0JxSR9d7f3k,948
|
|
71
71
|
vendor/choosealicense.com/_licenses/zlib.txt,sha256=e6dfCeLhxD3NCnIkY4cVIagRaWdRvencjNhHZ1APvpc,1678
|
|
72
|
-
vendor/spdx/json/licenses.json,sha256=
|
|
73
|
-
owasp_depscan-6.0.
|
|
74
|
-
owasp_depscan-6.0.
|
|
75
|
-
owasp_depscan-6.0.
|
|
76
|
-
owasp_depscan-6.0.
|
|
77
|
-
owasp_depscan-6.0.
|
|
72
|
+
vendor/spdx/json/licenses.json,sha256=oX5m9JJrCfwIWQt-Sxc--jPpBEKLcNKEyNA0S8VZO9U,325278
|
|
73
|
+
owasp_depscan-6.0.0b4.dist-info/METADATA,sha256=_Q442bFhNyp9BuB2Cmi8lnhA7HWaFX9CBpb6h7SbJ_c,17638
|
|
74
|
+
owasp_depscan-6.0.0b4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
75
|
+
owasp_depscan-6.0.0b4.dist-info/entry_points.txt,sha256=QvBVhjzm1Vx1CQkACbQWeNykZInIXUFUi6scoOYA7XY,45
|
|
76
|
+
owasp_depscan-6.0.0b4.dist-info/top_level.txt,sha256=qbHOZvNU2dXANv946hMdP2vOi0ESQB5t2ZY5ktKtXvQ,15
|
|
77
|
+
owasp_depscan-6.0.0b4.dist-info/RECORD,,
|
|
@@ -8,8 +8,8 @@ how: Create a text file (typically named LICENSE.md) in the root of your source
|
|
|
8
8
|
|
|
9
9
|
using:
|
|
10
10
|
drone-gc: https://github.com/drone/drone-gc/blob/master/LICENSE.md
|
|
11
|
+
Lil Scan: https://github.com/judofyr/lil-scan/blob/main/LICENSE.md
|
|
11
12
|
oh-my-git: https://github.com/git-learning-game/oh-my-git/blob/main/LICENSE.md
|
|
12
|
-
punct: https://github.com/otherjoel/punct/blob/main/LICENSE.md
|
|
13
13
|
|
|
14
14
|
permissions:
|
|
15
15
|
- commercial-use
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: Open Software License 3.0
|
|
3
3
|
spdx-id: OSL-3.0
|
|
4
4
|
|
|
5
|
-
description:
|
|
5
|
+
description: Permissions of this copyleft license are conditioned on distributing source code of licensed works and modifications under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. Using the work or modifications to provide services to external users is treated as distribution and also requires making source code available. Works that merely link to a licensed work are considered collective works and are not subject to the license's reciprocity requirements.
|
|
6
6
|
|
|
7
7
|
how: Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Files licensed under OSL 3.0 must also include the notice "Licensed under the Open Software License version 3.0" adjacent to the copyright notice.
|
|
8
8
|
|