owasp-depscan 5.1.7__tar.gz → 5.2.0__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.

Files changed (87) hide show
  1. {owasp-depscan-5.1.7/owasp_depscan.egg-info → owasp-depscan-5.2.0}/PKG-INFO +1 -1
  2. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/cli.py +13 -2
  3. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/analysis.py +58 -20
  4. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/config.py +4 -0
  5. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/explainer.py +42 -16
  6. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/normalize.py +1 -1
  7. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0/owasp_depscan.egg-info}/PKG-INFO +1 -1
  8. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/pyproject.toml +1 -1
  9. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/LICENSE +0 -0
  10. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/MANIFEST.in +0 -0
  11. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/README.md +0 -0
  12. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/__init__.py +0 -0
  13. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/__init__.py +0 -0
  14. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/audit.py +0 -0
  15. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/bom.py +0 -0
  16. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/csaf.py +0 -0
  17. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/github.py +0 -0
  18. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/license.py +0 -0
  19. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/logger.py +0 -0
  20. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/orasclient.py +0 -0
  21. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/pkg_query.py +0 -0
  22. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/depscan/lib/utils.py +0 -0
  23. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/owasp_depscan.egg-info/SOURCES.txt +0 -0
  24. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/owasp_depscan.egg-info/dependency_links.txt +0 -0
  25. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/owasp_depscan.egg-info/entry_points.txt +0 -0
  26. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/owasp_depscan.egg-info/requires.txt +0 -0
  27. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/owasp_depscan.egg-info/top_level.txt +0 -0
  28. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/setup.cfg +0 -0
  29. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_analysis.py +0 -0
  30. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_bom.py +0 -0
  31. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_csaf.py +0 -0
  32. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_explainer.py +0 -0
  33. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_github.py +0 -0
  34. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_license.py +0 -0
  35. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_norm.py +0 -0
  36. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_pkg_query.py +0 -0
  37. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/test/test_utils.py +0 -0
  38. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/__init__.py +0 -0
  39. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_data/fields.yml +0 -0
  40. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_data/meta.yml +0 -0
  41. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_data/rules.yml +0 -0
  42. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/0bsd.txt +0 -0
  43. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -0
  44. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -0
  45. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/apache-2.0.txt +0 -0
  46. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/artistic-2.0.txt +0 -0
  47. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +0 -0
  48. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -0
  49. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +0 -0
  50. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +0 -0
  51. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/bsl-1.0.txt +0 -0
  52. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +0 -0
  53. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +0 -0
  54. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cc0-1.0.txt +0 -0
  55. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cecill-2.1.txt +0 -0
  56. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cern-ohl-p-2.0.txt +0 -0
  57. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cern-ohl-s-2.0.txt +0 -0
  58. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/cern-ohl-w-2.0.txt +0 -0
  59. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/ecl-2.0.txt +0 -0
  60. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/epl-1.0.txt +0 -0
  61. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/epl-2.0.txt +0 -0
  62. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -0
  63. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -0
  64. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/gfdl-1.3.txt +0 -0
  65. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/gpl-2.0.txt +0 -0
  66. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/gpl-3.0.txt +0 -0
  67. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/isc.txt +0 -0
  68. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -0
  69. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -0
  70. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +0 -0
  71. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/mit-0.txt +0 -0
  72. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/mit.txt +0 -0
  73. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -0
  74. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -0
  75. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -0
  76. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt +0 -0
  77. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/ncsa.txt +0 -0
  78. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/odbl-1.0.txt +0 -0
  79. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/ofl-1.1.txt +0 -0
  80. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/osl-3.0.txt +0 -0
  81. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/postgresql.txt +0 -0
  82. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/unlicense.txt +0 -0
  83. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/upl-1.0.txt +0 -0
  84. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/vim.txt +0 -0
  85. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -0
  86. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/vendor/choosealicense.com/_licenses/zlib.txt +0 -0
  87. {owasp-depscan-5.1.7 → owasp-depscan-5.2.0}/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.1.7
3
+ Version: 5.2.0
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
@@ -727,7 +727,14 @@ def main():
727
727
  """
728
728
  args = build_args()
729
729
  # declare variables that get initialized only conditionally
730
- summary, vdr_file, bom_file, pkg_list, pkg_vulnerabilities, pkg_group_rows = None, None, None, None, None, None
730
+ (
731
+ summary,
732
+ vdr_file,
733
+ bom_file,
734
+ pkg_list,
735
+ pkg_vulnerabilities,
736
+ pkg_group_rows,
737
+ ) = (None, None, None, None, None, None)
731
738
  # Should we turn on the debug mode
732
739
  if args.enable_debug:
733
740
  os.environ["AT_DEBUG_MODE"] = "debug"
@@ -738,7 +745,11 @@ def main():
738
745
  print(LOGO)
739
746
  src_dir = args.src_dir_image
740
747
  if not src_dir or src_dir == ".":
741
- src_dir = os.getcwd()
748
+ if src_dir == ".":
749
+ src_dir = os.getcwd()
750
+ # Try to infer from the bom file
751
+ elif args.bom and os.path.exists(args.bom):
752
+ src_dir = os.path.dirname(os.path.realpath(args.bom))
742
753
  reports_dir = args.reports_dir
743
754
  if args.csaf:
744
755
  toml_file_path = os.getenv(
@@ -25,7 +25,6 @@ from depscan.lib import config
25
25
  from depscan.lib.logger import LOG, console
26
26
  from depscan.lib.utils import max_version
27
27
 
28
-
29
28
  NEWLINE = "\\n"
30
29
 
31
30
  CWE_SPLITTER = re.compile(r"(?<=CWE-)[0-9]\d{0,5}", re.IGNORECASE)
@@ -225,6 +224,27 @@ def pkg_sub_tree(
225
224
  )
226
225
 
227
226
 
227
+ def is_os_target_sw(package_issue):
228
+ """
229
+ Since we rely on NVD, we filter those target_sw that definitely belong to a language
230
+ """
231
+ if package_issue and package_issue["affected_location"].get("cpe_uri"):
232
+ all_parts = CPE_FULL_REGEX.match(
233
+ package_issue["affected_location"].get("cpe_uri")
234
+ )
235
+ if (
236
+ all_parts
237
+ and all_parts.group("target_sw") != "*"
238
+ and (
239
+ all_parts.group("target_sw") in config.LANG_PKG_TYPES.keys()
240
+ or all_parts.group("target_sw")
241
+ in config.LANG_PKG_TYPES.values()
242
+ )
243
+ ):
244
+ return False
245
+ return True
246
+
247
+
228
248
  @dataclass
229
249
  class PrepareVdrOptions:
230
250
  project_type: str
@@ -338,15 +358,43 @@ def prepare_vdr(options: PrepareVdrOptions):
338
358
  insights = []
339
359
  plain_insights = []
340
360
  purl_obj = None
341
- vendor = None
342
- if purl and purl.startswith("pkg:"):
361
+ vendor = package_issue["affected_location"].get("vendor")
362
+ # If the match was based on name and version alone then the alias might legitimately lack a full purl
363
+ # Such results are usually false positives but could yield good hits at times
364
+ # So, instead of suppressing fully we try our best to tune and reduce the FP
365
+ if not purl.startswith("pkg:"):
366
+ if options.project_type in config.OS_PKG_TYPES:
367
+ if vendor and (
368
+ vendor in config.LANG_PKG_TYPES.values()
369
+ or vendor in config.LANG_PKG_TYPES.keys()
370
+ ):
371
+ fp_count += 1
372
+ continue
373
+ # Some nvd data might match application CVEs for
374
+ # OS vendors which can be filtered
375
+ if not is_os_target_sw(package_issue):
376
+ fp_count += 1
377
+ continue
378
+ else:
343
379
  purl_obj = parse_purl(purl)
344
380
  if purl_obj:
345
381
  version_used = purl_obj.get("version")
346
382
  package_type = purl_obj.get("type")
347
383
  qualifiers = purl_obj.get("qualifiers", {})
348
384
  if package_type in config.OS_PKG_TYPES:
349
- vendor = package_issue["affected_location"].get("vendor")
385
+ # Bug #208 - do not report application CVEs
386
+ if vendor and (
387
+ vendor in config.LANG_PKG_TYPES.values()
388
+ or vendor in config.LANG_PKG_TYPES.keys()
389
+ ):
390
+ fp_count += 1
391
+ continue
392
+ if package_type and (
393
+ package_type in config.LANG_PKG_TYPES.values()
394
+ or package_type in config.LANG_PKG_TYPES.keys()
395
+ ):
396
+ fp_count += 1
397
+ continue
350
398
  if (
351
399
  vendor
352
400
  and oci_product_types
@@ -358,20 +406,9 @@ def prepare_vdr(options: PrepareVdrOptions):
358
406
  continue
359
407
  # Some nvd data might match application CVEs for
360
408
  # OS vendors which can be filtered
361
- if package_issue["affected_location"].get("cpe_uri"):
362
- all_parts = CPE_FULL_REGEX.match(
363
- package_issue["affected_location"].get(
364
- "cpe_uri"
365
- )
366
- )
367
- if (
368
- all_parts
369
- and all_parts.group("target_sw") != "*"
370
- and all_parts.group("target_sw")
371
- not in config.OS_PKG_TYPES
372
- ):
373
- fp_count += 1
374
- continue
409
+ if not is_os_target_sw(package_issue):
410
+ fp_count += 1
411
+ continue
375
412
  insights.append(
376
413
  f"[#7C8082]:telescope: Vendor {vendor}[/#7C8082]"
377
414
  )
@@ -659,8 +696,9 @@ def prepare_vdr(options: PrepareVdrOptions):
659
696
  # If the user doesn't want any table output return quickly
660
697
  if options.no_vuln_table:
661
698
  return pkg_vulnerabilities, pkg_group_rows
662
- console.print()
663
- console.print(table)
699
+ if pkg_vulnerabilities:
700
+ console.print()
701
+ console.print(table)
664
702
  if pkg_group_rows:
665
703
  psection = Markdown(
666
704
  """
@@ -196,9 +196,12 @@ LANG_PKG_TYPES = {
196
196
  "groovy": "maven",
197
197
  "kotlin": "maven",
198
198
  "scala": "maven",
199
+ "jenkins": "maven",
199
200
  "js": "npm",
200
201
  "javascript": "npm",
201
202
  "nodejs": "npm",
203
+ "node.js": "npm",
204
+ "npmjs": "npm",
202
205
  "go": "golang",
203
206
  "golang": "golang",
204
207
  "ruby": "gem",
@@ -206,6 +209,7 @@ LANG_PKG_TYPES = {
206
209
  "dotnet": "nuget",
207
210
  "csharp": "nuget",
208
211
  "rust": "cargo",
212
+ "crates": "cargo",
209
213
  "dart": "pub",
210
214
  "cpp": "conan",
211
215
  "clojure": "clojars",
@@ -42,7 +42,7 @@ def explain(
42
42
  if reachables_slices_file:
43
43
  with open(reachables_slices_file, "r", encoding="utf-8") as f:
44
44
  reachables_data = json.load(f)
45
- if reachables_data:
45
+ if reachables_data and reachables_data.get("reachables"):
46
46
  rsection = Markdown(
47
47
  """## Reachable Flows
48
48
 
@@ -50,7 +50,9 @@ Below are some reachable flows identified by depscan. Use the provided tips to i
50
50
  """
51
51
  )
52
52
  console.print(rsection)
53
- explain_reachables(reachables_data, pkg_group_rows, project_type)
53
+ explain_reachables(
54
+ reachables_data, pkg_group_rows, project_type
55
+ )
54
56
 
55
57
 
56
58
  def explain_reachables(reachables, pkg_group_rows, project_type):
@@ -75,7 +77,7 @@ def explain_reachables(reachables, pkg_group_rows, project_type):
75
77
  flow_tree, comment, source_sink_desc, has_check_tag = explain_flows(
76
78
  areach.get("flows"), areach.get("purls"), project_type
77
79
  )
78
- if not source_sink_desc:
80
+ if not source_sink_desc or not flow_tree:
79
81
  continue
80
82
  rtable = Table(
81
83
  box=box.DOUBLE_EDGE,
@@ -111,7 +113,7 @@ def explain_reachables(reachables, pkg_group_rows, project_type):
111
113
  console.print(rsection)
112
114
 
113
115
 
114
- def flow_to_source_sink(flow, purls, project_type):
116
+ def flow_to_source_sink(idx, flow, purls, project_type):
115
117
  """ """
116
118
  source_sink_desc = ""
117
119
  param_name = flow.get("name")
@@ -119,15 +121,23 @@ def flow_to_source_sink(flow, purls, project_type):
119
121
  param_str = "Parameter"
120
122
  if param_name == "this":
121
123
  param_name = ""
124
+ parent_file = flow.get("parentFileName", "")
125
+ parent_method = flow.get("parentMethodName", "")
122
126
  # Improve the labels based on the language
123
- if re.search(".(js|ts|jsx|tsx|py|cs)$", flow.get("parentFileName", "")):
127
+ if re.search(".(js|ts|jsx|tsx|py|cs|php)$", parent_file):
124
128
  method_str = "function"
125
129
  param_str = "argument"
130
+ if parent_method in ("handleRequest",):
131
+ method_str = f"handler {method_str}"
132
+ elif parent_method in ("__construct", "__init"):
133
+ method_str = f"constructor"
134
+ elif project_type in ("php",) and parent_method.startswith("__"):
135
+ method_str = f"magic {method_str}"
126
136
  if flow.get("label") == "METHOD_PARAMETER_IN":
127
137
  if param_name:
128
- source_sink_desc = f"""{param_str} [red]{param_name}[/red] :right_arrow_curving_left: to the {method_str} [bold]{flow.get('parentMethodName')}[/bold]"""
138
+ source_sink_desc = f"""{param_str} [red]{param_name}[/red] :right_arrow_curving_left: to the {method_str} [bold]{parent_method}[/bold]"""
129
139
  else:
130
- source_sink_desc = f"""{method_str.capitalize()} [red]{flow.get('parentMethodName')}[/red] :right_arrow_curving_left:"""
140
+ source_sink_desc = f"""{method_str.capitalize()} [red]{parent_method}[/red] :right_arrow_curving_left:"""
131
141
  elif flow.get("label") == "CALL" and flow.get("isExternal"):
132
142
  method_full_name = flow.get("fullName", "")
133
143
  if not method_full_name.startswith("<"):
@@ -148,11 +158,14 @@ def flow_to_source_sink(flow, purls, project_type):
148
158
  ):
149
159
  source_sink_desc = "Flow starts from a callback function"
150
160
  elif (
151
- "middleware" in source_sink_desc.lower() or "route" in source_sink_desc.lower()
161
+ "middleware" in source_sink_desc.lower()
162
+ or "route" in source_sink_desc.lower()
152
163
  ):
153
164
  source_sink_desc = "Flow starts from a middlware"
154
165
  elif len(purls) == 1:
155
- source_sink_desc = f"{source_sink_desc} can be used to reach this package."
166
+ source_sink_desc = (
167
+ f"{source_sink_desc} can be used to reach this package."
168
+ )
156
169
  else:
157
170
  source_sink_desc = (
158
171
  f"{source_sink_desc} can be used to reach {len(purls)} packages."
@@ -165,7 +178,8 @@ def filter_tags(tags):
165
178
  tags = [
166
179
  atag
167
180
  for atag in tags.split(", ")
168
- if atag not in ("RESOLVED_MEMBER", "UNKNOWN_METHOD", "UNKNOWN_TYPE_DECL")
181
+ if atag
182
+ not in ("RESOLVED_MEMBER", "UNKNOWN_METHOD", "UNKNOWN_TYPE_DECL")
169
183
  ]
170
184
  return ", ".join(tags)
171
185
  return tags
@@ -189,12 +203,16 @@ def flow_to_str(flow, project_type):
189
203
  param_name = ""
190
204
  node_desc = f'{flow.get("parentMethodName")}([red]{param_name}[/red]) :right_arrow_curving_left:'
191
205
  if tags:
192
- node_desc = f"{node_desc}\n[bold]Tags:[/bold] [italic]{tags}[/italic]\n"
206
+ node_desc = (
207
+ f"{node_desc}\n[bold]Tags:[/bold] [italic]{tags}[/italic]\n"
208
+ )
193
209
  elif flow.get("label") == "IDENTIFIER":
194
210
  if node_desc.startswith("<"):
195
211
  node_desc = flow.get("name")
196
212
  if tags:
197
- node_desc = f"{node_desc}\n[bold]Tags:[/bold] [italic]{tags}[/italic]\n"
213
+ node_desc = (
214
+ f"{node_desc}\n[bold]Tags:[/bold] [italic]{tags}[/italic]\n"
215
+ )
198
216
  if tags:
199
217
  for ctag in (
200
218
  "validation",
@@ -209,7 +227,11 @@ def flow_to_str(flow, project_type):
209
227
  break
210
228
  if has_check_tag:
211
229
  node_desc = f"[green]{node_desc}[/green]"
212
- return file_loc, f"""[gray37]{file_loc}[/gray37]{node_desc}""", has_check_tag
230
+ return (
231
+ file_loc,
232
+ f"""[gray37]{file_loc}[/gray37]{node_desc}""",
233
+ has_check_tag,
234
+ )
213
235
 
214
236
 
215
237
  def explain_flows(flows, purls, project_type):
@@ -226,7 +248,7 @@ def explain_flows(flows, purls, project_type):
226
248
  has_check_tag = False
227
249
  last_file_loc = None
228
250
  source_sink_desc = ""
229
- for aflow in flows:
251
+ for idx, aflow in enumerate(flows):
230
252
  # For java, we are only interested in identifiers with tags to keep the flows simple to understand
231
253
  if (
232
254
  project_type in ("java", "jar", "android", "apk")
@@ -235,8 +257,12 @@ def explain_flows(flows, purls, project_type):
235
257
  ):
236
258
  continue
237
259
  if not source_sink_desc:
238
- source_sink_desc = flow_to_source_sink(aflow, purls, project_type)
239
- file_loc, flow_str, has_check_tag_flow = flow_to_str(aflow, project_type)
260
+ source_sink_desc = flow_to_source_sink(
261
+ idx, aflow, purls, project_type
262
+ )
263
+ file_loc, flow_str, has_check_tag_flow = flow_to_str(
264
+ aflow, project_type
265
+ )
240
266
  if last_file_loc == file_loc:
241
267
  continue
242
268
  last_file_loc = file_loc
@@ -194,7 +194,7 @@ def create_pkg_variations(pkg_dict):
194
194
  for nvar in list(name_aliases):
195
195
  pkg_list.append(
196
196
  {
197
- "vendor": pkg_dict.get("vendor"),
197
+ "vendor": pkg_dict.get("vendor"), # Could be none which is fine
198
198
  "name": nvar,
199
199
  "version": pkg_dict["version"],
200
200
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: owasp-depscan
3
- Version: 5.1.7
3
+ Version: 5.2.0
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "owasp-depscan"
3
- version = "5.1.7"
3
+ version = "5.2.0"
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"},
File without changes
File without changes
File without changes
File without changes