owasp-depscan 5.3.5__tar.gz → 5.4.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 (89) hide show
  1. {owasp_depscan-5.3.5/owasp_depscan.egg-info → owasp_depscan-5.4.0}/PKG-INFO +5 -31
  2. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/README.md +3 -29
  3. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/cli.py +38 -31
  4. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/analysis.py +41 -25
  5. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/pkg_query.py +57 -22
  6. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0/owasp_depscan.egg-info}/PKG-INFO +5 -31
  7. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/owasp_depscan.egg-info/SOURCES.txt +2 -0
  8. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/owasp_depscan.egg-info/requires.txt +1 -1
  9. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/pyproject.toml +2 -2
  10. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_pkg_query.py +3 -3
  11. owasp_depscan-5.4.0/vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt +84 -0
  12. owasp_depscan-5.4.0/vendor/choosealicense.com/_licenses/bsd-2-clause-patent.txt +76 -0
  13. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/gpl-2.0.txt +1 -1
  14. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/upl-1.0.txt +1 -1
  15. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/spdx/json/licenses.json +1254 -615
  16. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/LICENSE +0 -0
  17. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/MANIFEST.in +0 -0
  18. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/__init__.py +0 -0
  19. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/__init__.py +0 -0
  20. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/audit.py +0 -0
  21. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/bom.py +0 -0
  22. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/config.py +0 -0
  23. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/csaf.py +0 -0
  24. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/explainer.py +0 -0
  25. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/github.py +0 -0
  26. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/license.py +0 -0
  27. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/logger.py +0 -0
  28. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/normalize.py +0 -0
  29. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/orasclient.py +0 -0
  30. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/depscan/lib/utils.py +0 -0
  31. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/owasp_depscan.egg-info/dependency_links.txt +0 -0
  32. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/owasp_depscan.egg-info/entry_points.txt +0 -0
  33. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/owasp_depscan.egg-info/top_level.txt +0 -0
  34. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/setup.cfg +0 -0
  35. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_analysis.py +0 -0
  36. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_bom.py +0 -0
  37. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_csaf.py +0 -0
  38. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_explainer.py +0 -0
  39. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_github.py +0 -0
  40. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_license.py +0 -0
  41. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_norm.py +0 -0
  42. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/test/test_utils.py +0 -0
  43. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/__init__.py +0 -0
  44. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_data/fields.yml +0 -0
  45. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_data/meta.yml +0 -0
  46. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_data/rules.yml +0 -0
  47. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/0bsd.txt +0 -0
  48. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -0
  49. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -0
  50. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/apache-2.0.txt +0 -0
  51. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/artistic-2.0.txt +0 -0
  52. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +0 -0
  53. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -0
  54. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +0 -0
  55. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +0 -0
  56. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/bsl-1.0.txt +0 -0
  57. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +0 -0
  58. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +0 -0
  59. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cc0-1.0.txt +0 -0
  60. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cecill-2.1.txt +0 -0
  61. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cern-ohl-p-2.0.txt +0 -0
  62. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cern-ohl-s-2.0.txt +0 -0
  63. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/cern-ohl-w-2.0.txt +0 -0
  64. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/ecl-2.0.txt +0 -0
  65. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/epl-1.0.txt +0 -0
  66. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/epl-2.0.txt +0 -0
  67. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -0
  68. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -0
  69. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/gfdl-1.3.txt +0 -0
  70. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/gpl-3.0.txt +0 -0
  71. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/isc.txt +0 -0
  72. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -0
  73. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -0
  74. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +0 -0
  75. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/mit-0.txt +0 -0
  76. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/mit.txt +0 -0
  77. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -0
  78. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -0
  79. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -0
  80. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt +0 -0
  81. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/ncsa.txt +0 -0
  82. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/odbl-1.0.txt +0 -0
  83. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/ofl-1.1.txt +0 -0
  84. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/osl-3.0.txt +0 -0
  85. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/postgresql.txt +0 -0
  86. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/unlicense.txt +0 -0
  87. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/vim.txt +0 -0
  88. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -0
  89. {owasp_depscan-5.3.5 → owasp_depscan-5.4.0}/vendor/choosealicense.com/_licenses/zlib.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: owasp-depscan
3
- Version: 5.3.5
3
+ Version: 5.4.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
@@ -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.6.8
23
+ Requires-Dist: appthreat-vulnerability-db==5.7.1
24
24
  Requires-Dist: defusedxml
25
25
  Requires-Dist: oras~=0.1.26
26
26
  Requires-Dist: PyYAML
@@ -138,27 +138,6 @@ oras pull ghcr.io/owasp-dep-scan/depscan:v4 -o $VDB_HOME
138
138
 
139
139
  Use `vdb-10y` which is a larger database with vulnerability data spanning the last 10 years from 2014. In contrast, vdb with a starting year of 2018 is appropriate for most users.
140
140
 
141
- ### Single binary executables
142
-
143
- Download the executable binary for your operating system from the [releases page](https://github.com/owasp-dep-scan/depscan-bin/releases). These binary bundle the following:
144
-
145
- - dep-scan with Python 3.11
146
- - cdxgen with Node.js 21
147
- - cdxgen binary plugins
148
-
149
- ```bash
150
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan-linux-amd64
151
- chmod +x depscan-linux-amd64
152
- ./depscan-linux-amd64 --help
153
- ```
154
-
155
- On Windows,
156
-
157
- ```powershell
158
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan.exe
159
- .\depscan.exe --help
160
- ```
161
-
162
141
  ### Server mode
163
142
 
164
143
  dep-scan and cdxgen could be run in server mode. Use the included docker-compose file to get started.
@@ -190,19 +169,14 @@ Use the `/scan` endpoint to perform scans.
190
169
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
191
170
  ```
192
171
 
193
- - Scanning a SBOM file (present locally).
172
+ - Scanning an SBOM file (present locally).
194
173
 
195
174
  ```bash
196
175
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
197
176
  ```
198
177
 
199
178
  - Scanning a GitHub repo.
200
-
201
- ```bash
202
- curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
203
- ```
204
-
205
- - Uploading a SBOM file and generating results based on it.
179
+ Uploading an SBOM file and generating results based on it.
206
180
 
207
181
  ```bash
208
182
  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
@@ -307,7 +281,7 @@ You can also specify the image using the sha256 digest
307
281
  depscan --src redmine@sha256:a5c5f8a64a0d9a436a0a6941bc3fb156be0c89996add834fe33b66ebeed2439e -o containertests/depscan-redmine.json -t docker
308
282
  ```
309
283
 
310
- You can also save container images using docker or podman save command and pass the archive to depscan for scanning.
284
+ You can also save container images using the docker or podman save command and pass the archive to depscan for scanning.
311
285
 
312
286
  ```bash
313
287
  docker save -o /tmp/scanslim.tar shiftleft/scan-slim:latest
@@ -97,27 +97,6 @@ oras pull ghcr.io/owasp-dep-scan/depscan:v4 -o $VDB_HOME
97
97
 
98
98
  Use `vdb-10y` which is a larger database with vulnerability data spanning the last 10 years from 2014. In contrast, vdb with a starting year of 2018 is appropriate for most users.
99
99
 
100
- ### Single binary executables
101
-
102
- Download the executable binary for your operating system from the [releases page](https://github.com/owasp-dep-scan/depscan-bin/releases). These binary bundle the following:
103
-
104
- - dep-scan with Python 3.11
105
- - cdxgen with Node.js 21
106
- - cdxgen binary plugins
107
-
108
- ```bash
109
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan-linux-amd64
110
- chmod +x depscan-linux-amd64
111
- ./depscan-linux-amd64 --help
112
- ```
113
-
114
- On Windows,
115
-
116
- ```powershell
117
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan.exe
118
- .\depscan.exe --help
119
- ```
120
-
121
100
  ### Server mode
122
101
 
123
102
  dep-scan and cdxgen could be run in server mode. Use the included docker-compose file to get started.
@@ -149,19 +128,14 @@ Use the `/scan` endpoint to perform scans.
149
128
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
150
129
  ```
151
130
 
152
- - Scanning a SBOM file (present locally).
131
+ - Scanning an SBOM file (present locally).
153
132
 
154
133
  ```bash
155
134
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
156
135
  ```
157
136
 
158
137
  - Scanning a GitHub repo.
159
-
160
- ```bash
161
- curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
162
- ```
163
-
164
- - Uploading a SBOM file and generating results based on it.
138
+ Uploading an SBOM file and generating results based on it.
165
139
 
166
140
  ```bash
167
141
  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
@@ -266,7 +240,7 @@ You can also specify the image using the sha256 digest
266
240
  depscan --src redmine@sha256:a5c5f8a64a0d9a436a0a6941bc3fb156be0c89996add834fe33b66ebeed2439e -o containertests/depscan-redmine.json -t docker
267
241
  ```
268
242
 
269
- You can also save container images using docker or podman save command and pass the archive to depscan for scanning.
243
+ You can also save container images using the docker or podman save command and pass the archive to depscan for scanning.
270
244
 
271
245
  ```bash
272
246
  docker save -o /tmp/scanslim.tar shiftleft/scan-slim:latest
@@ -80,7 +80,7 @@ def build_args():
80
80
  action="store_true",
81
81
  default=False,
82
82
  dest="no_banner",
83
- help="Do not display banner",
83
+ help="Do not display the logo and donation banner. Please make a donation to OWASP before using this argument.",
84
84
  )
85
85
  parser.add_argument(
86
86
  "--cache",
@@ -137,7 +137,7 @@ def build_args():
137
137
  "--cdxgen-args",
138
138
  default=os.getenv("CDXGEN_ARGS"),
139
139
  dest="cdxgen_args",
140
- help="Additional arguments to pass to cdxgen"
140
+ help="Additional arguments to pass to cdxgen",
141
141
  )
142
142
  parser.add_argument(
143
143
  "--private-ns",
@@ -741,6 +741,7 @@ def main():
741
741
  and generates reports based on the results.
742
742
  """
743
743
  args = build_args()
744
+ perform_risk_audit = args.risk_audit
744
745
  # declare variables that get initialized only conditionally
745
746
  (
746
747
  summary,
@@ -750,21 +751,19 @@ def main():
750
751
  pkg_vulnerabilities,
751
752
  pkg_group_rows,
752
753
  ) = (None, None, None, None, None, None)
753
- if os.getenv("GITHUB_ACTION", "").lower() == "__appthreat_dep-scan-action" \
754
- and not os.getenv("INPUT_THANK_YOU", "") == ("I have sponsored "
755
- "OWASP-dep-scan."):
754
+ if (
755
+ os.getenv("CI")
756
+ and not args.no_banner
757
+ and not os.getenv("INPUT_THANK_YOU", "")
758
+ == ("I have sponsored OWASP-dep-scan.")
759
+ ):
756
760
  console.print(
757
761
  Panel(
758
- "OWASP relies on donations to fund our projects.\n\n"
759
- "Donate at: https://owasp.org/donate/?reponame=www-project"
760
- "-dep-scan&title=OWASP+depscan.\n\nAfter you have done so, "
761
- "make sure you have configured the action with thank_you: 'I "
762
- "have sponsored OWASP-dep-scan.'",
763
- title="Please make a donation",
762
+ "OWASP foundation relies on donations to fund our projects.\nPlease donate at: https://owasp.org/donate/?reponame=www-project-dep-scan&title=OWASP+depscan",
763
+ title="Donate to the OWASP Foundation",
764
764
  expand=False,
765
765
  )
766
766
  )
767
- sys.exit(1)
768
767
  # Should we turn on the debug mode
769
768
  if args.enable_debug:
770
769
  os.environ["AT_DEBUG_MODE"] = "debug"
@@ -808,6 +807,8 @@ def main():
808
807
  if args.project_type:
809
808
  project_types_list = args.project_type.split(",")
810
809
  elif args.search_purl:
810
+ # Automatically enable risk audit for single purl searches
811
+ perform_risk_audit = True
811
812
  purl_obj = parse_purl(args.search_purl)
812
813
  purl_obj["purl"] = args.search_purl
813
814
  purl_obj["vendor"] = purl_obj.get("namespace")
@@ -870,7 +871,11 @@ def main():
870
871
  bom_file,
871
872
  src_dir,
872
873
  args.deep_scan,
873
- {"cdxgen_server": args.cdxgen_server, "profile": args.profile, "cdxgen_args": args.cdxgen_args},
874
+ {
875
+ "cdxgen_server": args.cdxgen_server,
876
+ "profile": args.profile,
877
+ "cdxgen_args": args.cdxgen_args,
878
+ },
874
879
  )
875
880
  if not creation_status:
876
881
  LOG.debug("Bom file %s was not created successfully", bom_file)
@@ -903,16 +908,17 @@ def main():
903
908
  project_type, licenses_results, license_report_file
904
909
  )
905
910
  if project_type in risk_audit_map:
906
- if args.risk_audit:
907
- console.print(
908
- Panel(
909
- f"Performing OSS Risk Audit for packages from "
910
- f"{src_dir}\nNo of packages [bold]{len(pkg_list)}"
911
- f"[/bold]. This will take a while ...",
912
- title="OSS Risk Audit",
913
- expand=False,
911
+ if perform_risk_audit:
912
+ if len(pkg_list) > 1:
913
+ console.print(
914
+ Panel(
915
+ f"Performing OSS Risk Audit for packages from "
916
+ f"{src_dir}\nNo of packages [bold]{len(pkg_list)}"
917
+ f"[/bold]. This will take a while ...",
918
+ title="OSS Risk Audit",
919
+ expand=False,
920
+ )
914
921
  )
915
- )
916
922
  try:
917
923
  risk_results = risk_audit(
918
924
  project_type,
@@ -995,7 +1001,7 @@ def main():
995
1001
  github_client = github.GitHub(github_token)
996
1002
 
997
1003
  if not github_client.can_authenticate():
998
- LOG.error(
1004
+ LOG.info(
999
1005
  "The GitHub personal access token supplied appears to be invalid or expired. Please see: https://github.com/owasp-dep-scan/dep-scan#github-security-advisory"
1000
1006
  )
1001
1007
  else:
@@ -1021,11 +1027,12 @@ def main():
1021
1027
  except NotImplementedError:
1022
1028
  pass
1023
1029
  run_cacher = False
1024
- LOG.info(
1025
- "Performing regular scan for %s using plugin %s",
1026
- src_dir,
1027
- project_type,
1028
- )
1030
+ if len(pkg_list) > 1:
1031
+ LOG.info(
1032
+ "Performing regular scan for %s using plugin %s",
1033
+ src_dir,
1034
+ project_type,
1035
+ )
1029
1036
  vdb_results, pkg_aliases, sug_version_dict, purl_aliases = scan(
1030
1037
  db, project_type, pkg_list, args.suggest
1031
1038
  )
@@ -1071,9 +1078,9 @@ def main():
1071
1078
  )
1072
1079
  console.save_html(
1073
1080
  html_file,
1074
- theme=MONOKAI
1075
- if os.getenv("USE_DARK_THEME")
1076
- else DEFAULT_TERMINAL_THEME,
1081
+ theme=(
1082
+ MONOKAI if os.getenv("USE_DARK_THEME") else DEFAULT_TERMINAL_THEME
1083
+ ),
1077
1084
  )
1078
1085
  utils.export_pdf(html_file, pdf_file)
1079
1086
  # render report into template if wished
@@ -235,8 +235,7 @@ def is_lang_sw_edition(package_issue):
235
235
  return True
236
236
  if (
237
237
  config.LANG_PKG_TYPES.get(all_parts.group("sw_edition"))
238
- or all_parts.group("sw_edition")
239
- in config.LANG_PKG_TYPES.values()
238
+ or all_parts.group("sw_edition") in config.LANG_PKG_TYPES.values()
240
239
  ):
241
240
  return True
242
241
  return False
@@ -306,6 +305,7 @@ def prepare_vdr(options: PrepareVdrOptions):
306
305
  fp_count = 0
307
306
  pkg_attention_count = 0
308
307
  critical_count = 0
308
+ malicious_count = 0
309
309
  has_poc_count = 0
310
310
  has_reachable_poc_count = 0
311
311
  has_exploit_count = 0
@@ -376,6 +376,10 @@ def prepare_vdr(options: PrepareVdrOptions):
376
376
  package_type = None
377
377
  insights = []
378
378
  plain_insights = []
379
+ if vid.startswith("MAL-"):
380
+ insights.append("[bright_red]:stop_sign: Malicious[/bright_red]")
381
+ plain_insights.append("Malicious")
382
+ malicious_count += 1
379
383
  purl_obj = None
380
384
  vendor = package_issue["affected_location"].get("vendor")
381
385
  # If the match was based on name and version alone then the alias might legitimately lack a full purl
@@ -401,7 +405,13 @@ def prepare_vdr(options: PrepareVdrOptions):
401
405
  package_type = purl_obj.get("type")
402
406
  qualifiers = purl_obj.get("qualifiers", {})
403
407
  # Filter application CVEs from distros
404
- if (config.LANG_PKG_TYPES.get(package_type) or package_type in config.LANG_PKG_TYPES.values()) and ((vendor and vendor in config.OS_PKG_TYPES) or not is_lang_sw_edition(package_issue)):
408
+ if (
409
+ config.LANG_PKG_TYPES.get(package_type)
410
+ or package_type in config.LANG_PKG_TYPES.values()
411
+ ) and (
412
+ (vendor and vendor in config.OS_PKG_TYPES)
413
+ or not is_lang_sw_edition(package_issue)
414
+ ):
405
415
  fp_count += 1
406
416
  continue
407
417
  if package_type in config.OS_PKG_TYPES:
@@ -760,7 +770,18 @@ Below are the vulnerabilities prioritized by depscan. Follow your team's remedia
760
770
  console.print()
761
771
  console.print(utable)
762
772
  console.print()
763
- if options.scoped_pkgs or has_exploit_count:
773
+ if malicious_count:
774
+ rmessage = ":stop_sign: Malicious package found! Treat this as a [bold]security incident[/bold] and follow your organization's playbook to remove this package from all affected applications."
775
+ if malicious_count > 1:
776
+ rmessage = f":stop_sign: {malicious_count} malicious packages found in this project! Treat this as a [bold]security incident[/bold] and follow your organization's playbook to remove the packages from all affected applications."
777
+ console.print(
778
+ Panel(
779
+ rmessage,
780
+ title="Action Required",
781
+ expand=False,
782
+ )
783
+ )
784
+ elif options.scoped_pkgs or has_exploit_count:
764
785
  if not pkg_attention_count and has_exploit_count:
765
786
  if has_reachable_exploit_count:
766
787
  rmessage = (
@@ -898,18 +919,19 @@ Below are the vulnerabilities prioritized by depscan. Follow your team's remedia
898
919
  this result."""
899
920
  console.print(Panel(rmessage, title="Recommendation"))
900
921
  else:
901
- rmessage = ":white_check_mark: No package requires immediate attention."
922
+ rmessage = None
902
923
  if reached_purls:
903
924
  rmessage = ":white_check_mark: No package requires immediate attention since the major vulnerabilities are not reachable."
904
925
  elif direct_purls:
905
926
  rmessage = ":white_check_mark: No package requires immediate attention since the major vulnerabilities are found only in dev packages and indirect dependencies."
906
- console.print(
907
- Panel(
908
- rmessage,
909
- title="Recommendation",
910
- expand=False,
927
+ if rmessage:
928
+ console.print(
929
+ Panel(
930
+ rmessage,
931
+ title="Recommendation",
932
+ expand=False,
933
+ )
911
934
  )
912
- )
913
935
  elif critical_count:
914
936
  console.print(
915
937
  Panel(
@@ -919,14 +941,6 @@ Below are the vulnerabilities prioritized by depscan. Follow your team's remedia
919
941
  expand=False,
920
942
  )
921
943
  )
922
- else:
923
- console.print(
924
- Panel(
925
- ":white_check_mark: No package requires immediate attention.",
926
- title="Recommendation",
927
- expand=False,
928
- )
929
- )
930
944
  if reached_purls:
931
945
  sorted_reached_purls = sorted(
932
946
  ((value, key) for (key, value) in reached_purls.items()),
@@ -1329,12 +1343,14 @@ def analyse_licenses(project_type, licenses_results, license_report_file=None):
1329
1343
  data = [
1330
1344
  *pkg_ver,
1331
1345
  "{}{}".format(
1332
- "[cyan]"
1333
- if "GPL" in lic["spdx-id"]
1334
- or "CC-BY-" in lic["spdx-id"]
1335
- or "Facebook" in lic["spdx-id"]
1336
- or "WTFPL" in lic["spdx-id"]
1337
- else "",
1346
+ (
1347
+ "[cyan]"
1348
+ if "GPL" in lic["spdx-id"]
1349
+ or "CC-BY-" in lic["spdx-id"]
1350
+ or "Facebook" in lic["spdx-id"]
1351
+ or "WTFPL" in lic["spdx-id"]
1352
+ else ""
1353
+ ),
1338
1354
  lic["spdx-id"],
1339
1355
  ),
1340
1356
  conditions_str,
@@ -1,5 +1,6 @@
1
1
  import math
2
2
  from datetime import datetime
3
+ from semver import Version
3
4
 
4
5
  import httpx
5
6
  from rich.progress import Progress
@@ -40,7 +41,9 @@ def get_lookup_url(registry_type, pkg):
40
41
  return None, None
41
42
 
42
43
 
43
- def metadata_from_registry(registry_type, scoped_pkgs, pkg_list, private_ns=None):
44
+ def metadata_from_registry(
45
+ registry_type, scoped_pkgs, pkg_list, private_ns=None
46
+ ):
44
47
  """
45
48
  Method to query registry for the package metadata
46
49
 
@@ -64,7 +67,9 @@ def metadata_from_registry(registry_type, scoped_pkgs, pkg_list, private_ns=None
64
67
  redirect_stdout=False,
65
68
  refresh_per_second=1,
66
69
  ) as progress:
67
- task = progress.add_task("[green] Auditing packages", total=len(pkg_list))
70
+ task = progress.add_task(
71
+ "[green] Auditing packages", total=len(pkg_list)
72
+ )
68
73
  for pkg in pkg_list:
69
74
  if circuit_breaker:
70
75
  LOG.info(
@@ -96,14 +101,16 @@ def metadata_from_registry(registry_type, scoped_pkgs, pkg_list, private_ns=None
96
101
  if private_ns:
97
102
  namespace_prefixes = private_ns.split(",")
98
103
  for ns in namespace_prefixes:
99
- if key.lower().startswith(ns.lower()) or key.lower().startswith(
100
- "@" + ns.lower()
101
- ):
104
+ if key.lower().startswith(
105
+ ns.lower()
106
+ ) or key.lower().startswith("@" + ns.lower()):
102
107
  is_private_pkg = True
103
108
  break
104
109
  risk_metrics = {}
105
110
  if registry_type == "npm":
106
- risk_metrics = npm_pkg_risk(json_data, is_private_pkg, scope)
111
+ risk_metrics = npm_pkg_risk(
112
+ json_data, is_private_pkg, scope
113
+ )
107
114
  elif registry_type == "pypi":
108
115
  project_type_pkg = f"python:{key}".lower()
109
116
  required_pkgs = scoped_pkgs.get("required", [])
@@ -124,7 +131,9 @@ def metadata_from_registry(registry_type, scoped_pkgs, pkg_list, private_ns=None
124
131
  or project_type_pkg in excluded_pkgs
125
132
  ):
126
133
  scope = "excluded"
127
- risk_metrics = pypi_pkg_risk(json_data, is_private_pkg, scope)
134
+ risk_metrics = pypi_pkg_risk(
135
+ json_data, is_private_pkg, scope, pkg
136
+ )
128
137
  metadata_dict[key] = {
129
138
  "scope": scope,
130
139
  "pkg_metadata": json_data,
@@ -269,14 +278,17 @@ def compute_time_risks(
269
278
  # Check if the package is at least 1 year old. Quarantine period.
270
279
  if created_now_diff.total_seconds() < config.created_now_quarantine_seconds:
271
280
  risk_metrics["created_now_quarantine_seconds_risk"] = True
272
- risk_metrics[
273
- "created_now_quarantine_seconds_value"
274
- ] = latest_now_diff.total_seconds()
281
+ risk_metrics["created_now_quarantine_seconds_value"] = (
282
+ latest_now_diff.total_seconds()
283
+ )
275
284
 
276
285
  # Check for the maximum seconds difference between latest version and now
277
286
  if latest_now_diff.total_seconds() > config.latest_now_max_seconds:
287
+ print(latest_now_diff.total_seconds(), config.latest_now_max_seconds)
278
288
  risk_metrics["latest_now_max_seconds_risk"] = True
279
- risk_metrics["latest_now_max_seconds_value"] = latest_now_diff.total_seconds()
289
+ risk_metrics["latest_now_max_seconds_value"] = (
290
+ latest_now_diff.total_seconds()
291
+ )
280
292
  # Since the package is quite old we can relax the min versions risk
281
293
  risk_metrics["pkg_min_versions_risk"] = False
282
294
  else:
@@ -287,17 +299,19 @@ def compute_time_risks(
287
299
  # packages
288
300
  if mod_create_diff.total_seconds() < config.mod_create_min_seconds:
289
301
  risk_metrics["mod_create_min_seconds_risk"] = True
290
- risk_metrics[
291
- "mod_create_min_seconds_value"
292
- ] = mod_create_diff.total_seconds()
302
+ risk_metrics["mod_create_min_seconds_value"] = (
303
+ mod_create_diff.total_seconds()
304
+ )
293
305
  # Check for the minimum seconds difference between latest version and now
294
306
  if latest_now_diff.total_seconds() < config.latest_now_min_seconds:
295
307
  risk_metrics["latest_now_min_seconds_risk"] = True
296
- risk_metrics["latest_now_min_seconds_value"] = latest_now_diff.total_seconds()
308
+ risk_metrics["latest_now_min_seconds_value"] = (
309
+ latest_now_diff.total_seconds()
310
+ )
297
311
  return risk_metrics
298
312
 
299
313
 
300
- def pypi_pkg_risk(pkg_metadata, is_private_pkg, scope):
314
+ def pypi_pkg_risk(pkg_metadata, is_private_pkg, scope, pkg):
301
315
  """
302
316
  Calculate various package risks based on the metadata from pypi.
303
317
 
@@ -319,15 +333,38 @@ def pypi_pkg_risk(pkg_metadata, is_private_pkg, scope):
319
333
  versions_dict = pkg_metadata.get("releases", {})
320
334
  versions = [ver[0] for k, ver in versions_dict.items() if ver]
321
335
  is_deprecated = info.get("yanked") and info.get("yanked_reason")
336
+ if not is_deprecated and pkg and pkg.get("version"):
337
+ theversion = versions_dict.get(pkg.get("version"), [])
338
+ if isinstance(theversion, list):
339
+ theversion = theversion[0]
340
+ if theversion.get("yanked"):
341
+ is_deprecated = True
322
342
  # Some packages like pypi:azure only mention deprecated in the description
323
343
  # without yanking the package
324
344
  pkg_description = info.get("description", "").lower()
325
- if not is_deprecated and ("is deprecated" in pkg_description or "no longer maintained" in pkg_description):
345
+ if not is_deprecated and (
346
+ "is deprecated" in pkg_description
347
+ or "no longer maintained" in pkg_description
348
+ ):
326
349
  is_deprecated = True
327
350
  latest_deprecated = False
328
- first_version = None
329
- latest_version = None
330
-
351
+ version_nums = list(versions_dict.keys())
352
+ # Ignore empty versions without metadata. Thanks pypi
353
+ version_nums = [ver for ver in version_nums if versions_dict.get(ver)]
354
+ try:
355
+ first_version_num = min(
356
+ version_nums,
357
+ key=lambda x: Version.parse(x, optional_minor_and_patch=True),
358
+ )
359
+ latest_version_num = max(
360
+ version_nums,
361
+ key=lambda x: Version.parse(x, optional_minor_and_patch=True),
362
+ )
363
+ except (ValueError, TypeError):
364
+ first_version_num = version_nums[0]
365
+ latest_version_num = version_nums[-1]
366
+ first_version = versions_dict.get(first_version_num)[0]
367
+ latest_version = versions_dict.get(latest_version_num)[0]
331
368
  # Is the private package available publicly? Dependency confusion.
332
369
  if is_private_pkg and pkg_metadata:
333
370
  risk_metrics["pkg_private_on_public_registry_risk"] = True
@@ -338,8 +375,6 @@ def pypi_pkg_risk(pkg_metadata, is_private_pkg, scope):
338
375
  if len(versions) < config.pkg_min_versions:
339
376
  risk_metrics["pkg_min_versions_risk"] = True
340
377
  risk_metrics["pkg_min_versions_value"] = len(versions)
341
- first_version = versions[0]
342
- latest_version = versions[-1]
343
378
  # Check if the latest version is deprecated
344
379
  if latest_version and latest_version.get("yanked"):
345
380
  latest_deprecated = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: owasp-depscan
3
- Version: 5.3.5
3
+ Version: 5.4.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
@@ -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.6.8
23
+ Requires-Dist: appthreat-vulnerability-db==5.7.1
24
24
  Requires-Dist: defusedxml
25
25
  Requires-Dist: oras~=0.1.26
26
26
  Requires-Dist: PyYAML
@@ -138,27 +138,6 @@ oras pull ghcr.io/owasp-dep-scan/depscan:v4 -o $VDB_HOME
138
138
 
139
139
  Use `vdb-10y` which is a larger database with vulnerability data spanning the last 10 years from 2014. In contrast, vdb with a starting year of 2018 is appropriate for most users.
140
140
 
141
- ### Single binary executables
142
-
143
- Download the executable binary for your operating system from the [releases page](https://github.com/owasp-dep-scan/depscan-bin/releases). These binary bundle the following:
144
-
145
- - dep-scan with Python 3.11
146
- - cdxgen with Node.js 21
147
- - cdxgen binary plugins
148
-
149
- ```bash
150
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan-linux-amd64
151
- chmod +x depscan-linux-amd64
152
- ./depscan-linux-amd64 --help
153
- ```
154
-
155
- On Windows,
156
-
157
- ```powershell
158
- curl -LO https://github.com/owasp-dep-scan/depscan-bin/releases/latest/download/depscan.exe
159
- .\depscan.exe --help
160
- ```
161
-
162
141
  ### Server mode
163
142
 
164
143
  dep-scan and cdxgen could be run in server mode. Use the included docker-compose file to get started.
@@ -190,19 +169,14 @@ Use the `/scan` endpoint to perform scans.
190
169
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan
191
170
  ```
192
171
 
193
- - Scanning a SBOM file (present locally).
172
+ - Scanning an SBOM file (present locally).
194
173
 
195
174
  ```bash
196
175
  curl --json '{"path": "/tmp/vulnerable-aws-koa-app/sbom_file.json", "type": "js"}' http://0.0.0.0:7070/scan
197
176
  ```
198
177
 
199
178
  - Scanning a GitHub repo.
200
-
201
- ```bash
202
- curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan -o app.vdr.json
203
- ```
204
-
205
- - Uploading a SBOM file and generating results based on it.
179
+ Uploading an SBOM file and generating results based on it.
206
180
 
207
181
  ```bash
208
182
  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
@@ -307,7 +281,7 @@ You can also specify the image using the sha256 digest
307
281
  depscan --src redmine@sha256:a5c5f8a64a0d9a436a0a6941bc3fb156be0c89996add834fe33b66ebeed2439e -o containertests/depscan-redmine.json -t docker
308
282
  ```
309
283
 
310
- You can also save container images using docker or podman save command and pass the archive to depscan for scanning.
284
+ You can also save container images using the docker or podman save command and pass the archive to depscan for scanning.
311
285
 
312
286
  ```bash
313
287
  docker save -o /tmp/scanslim.tar shiftleft/scan-slim:latest
@@ -42,6 +42,8 @@ vendor/choosealicense.com/_licenses/afl-3.0.txt
42
42
  vendor/choosealicense.com/_licenses/agpl-3.0.txt
43
43
  vendor/choosealicense.com/_licenses/apache-2.0.txt
44
44
  vendor/choosealicense.com/_licenses/artistic-2.0.txt
45
+ vendor/choosealicense.com/_licenses/blueoak-1.0.0.txt
46
+ vendor/choosealicense.com/_licenses/bsd-2-clause-patent.txt
45
47
  vendor/choosealicense.com/_licenses/bsd-2-clause.txt
46
48
  vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt
47
49
  vendor/choosealicense.com/_licenses/bsd-3-clause.txt
@@ -1,4 +1,4 @@
1
- appthreat-vulnerability-db==5.6.8
1
+ appthreat-vulnerability-db==5.7.1
2
2
  defusedxml
3
3
  oras~=0.1.26
4
4
  PyYAML
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "owasp-depscan"
3
- version = "5.3.5"
3
+ version = "5.4.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"},
7
7
  ]
8
8
  dependencies = [
9
- "appthreat-vulnerability-db==5.6.8",
9
+ "appthreat-vulnerability-db==5.7.1",
10
10
  "defusedxml",
11
11
  "oras~=0.1.26",
12
12
  "PyYAML",