owasp-depscan 4.3.1__tar.gz → 4.3.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.

Files changed (86) hide show
  1. {owasp-depscan-4.3.1/owasp_depscan.egg-info → owasp-depscan-4.3.3}/PKG-INFO +49 -19
  2. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/README.md +46 -18
  3. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/cli.py +23 -3
  4. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/csaf.py +142 -95
  5. owasp-depscan-4.3.3/depscan/lib/github.py +62 -0
  6. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/utils.py +2 -2
  7. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3/owasp_depscan.egg-info}/PKG-INFO +49 -19
  8. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/owasp_depscan.egg-info/SOURCES.txt +2 -0
  9. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/owasp_depscan.egg-info/requires.txt +2 -0
  10. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/pyproject.toml +4 -2
  11. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_csaf.py +103 -29
  12. owasp-depscan-4.3.3/test/test_github.py +122 -0
  13. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/LICENSE +0 -0
  14. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/MANIFEST.in +0 -0
  15. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/__init__.py +0 -0
  16. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/__init__.py +0 -0
  17. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/analysis.py +0 -0
  18. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/audit.py +0 -0
  19. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/bom.py +0 -0
  20. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/config.py +0 -0
  21. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/license.py +0 -0
  22. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/logger.py +0 -0
  23. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/normalize.py +0 -0
  24. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/pkg_query.py +0 -0
  25. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/depscan/lib/privado.py +0 -0
  26. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/owasp_depscan.egg-info/dependency_links.txt +0 -0
  27. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/owasp_depscan.egg-info/entry_points.txt +0 -0
  28. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/owasp_depscan.egg-info/top_level.txt +0 -0
  29. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/setup.cfg +0 -0
  30. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_analysis.py +0 -0
  31. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_bom.py +0 -0
  32. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_license.py +0 -0
  33. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_norm.py +0 -0
  34. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_pkg_query.py +0 -0
  35. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_privado.py +0 -0
  36. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/test/test_utils.py +0 -0
  37. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/__init__.py +0 -0
  38. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_data/fields.yml +0 -0
  39. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_data/meta.yml +0 -0
  40. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_data/rules.yml +0 -0
  41. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/0bsd.txt +0 -0
  42. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/afl-3.0.txt +0 -0
  43. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -0
  44. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/apache-2.0.txt +0 -0
  45. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/artistic-2.0.txt +0 -0
  46. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +0 -0
  47. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +0 -0
  48. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +0 -0
  49. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +0 -0
  50. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/bsl-1.0.txt +0 -0
  51. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +0 -0
  52. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +0 -0
  53. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cc0-1.0.txt +0 -0
  54. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cecill-2.1.txt +0 -0
  55. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cern-ohl-p-2.0.txt +0 -0
  56. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cern-ohl-s-2.0.txt +0 -0
  57. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/cern-ohl-w-2.0.txt +0 -0
  58. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/ecl-2.0.txt +0 -0
  59. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/epl-1.0.txt +0 -0
  60. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/epl-2.0.txt +0 -0
  61. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -0
  62. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -0
  63. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/gfdl-1.3.txt +0 -0
  64. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/gpl-2.0.txt +0 -0
  65. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/gpl-3.0.txt +0 -0
  66. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/isc.txt +0 -0
  67. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -0
  68. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +0 -0
  69. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +0 -0
  70. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/mit-0.txt +0 -0
  71. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/mit.txt +0 -0
  72. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -0
  73. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -0
  74. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -0
  75. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/mulanpsl-2.0.txt +0 -0
  76. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/ncsa.txt +0 -0
  77. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/odbl-1.0.txt +0 -0
  78. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/ofl-1.1.txt +0 -0
  79. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/osl-3.0.txt +0 -0
  80. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/postgresql.txt +0 -0
  81. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/unlicense.txt +0 -0
  82. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/upl-1.0.txt +0 -0
  83. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/vim.txt +0 -0
  84. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -0
  85. {owasp-depscan-4.3.1 → owasp-depscan-4.3.3}/vendor/choosealicense.com/_licenses/zlib.txt +0 -0
  86. {owasp-depscan-4.3.1 → owasp-depscan-4.3.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: 4.3.1
3
+ Version: 4.3.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
@@ -26,12 +26,14 @@ Requires-Dist: oras
26
26
  Requires-Dist: PyYAML
27
27
  Requires-Dist: rich
28
28
  Requires-Dist: quart
29
+ Requires-Dist: PyGithub
29
30
  Requires-Dist: toml
30
31
  Provides-Extra: dev
31
32
  Requires-Dist: black; extra == "dev"
32
33
  Requires-Dist: flake8; extra == "dev"
33
34
  Requires-Dist: pytest; extra == "dev"
34
35
  Requires-Dist: pytest-cov; extra == "dev"
36
+ Requires-Dist: httpretty; extra == "dev"
35
37
 
36
38
  # Introduction
37
39
 
@@ -174,36 +176,60 @@ depscan --src $PWD --reports-dir $PWD/reports
174
176
  Full list of options are below:
175
177
 
176
178
  ```bash
177
- usage: depscan [-h] [--no-banner] [--cache] [--csaf] [--sync] [--suggest] [--risk-audit] [--private-ns PRIVATE_NS] [-t PROJECT_TYPE] [--bom BOM] [-i SRC_DIR_IMAGE] [-o REPORT_FILE] [--reports-dir REPORTS_DIR] [--no-error]
178
- [--no-license-scan] [--deep] [--no-universal] [--no-vuln-table] [--threatdb-server THREATDB_SERVER] [--threatdb-username THREATDB_USERNAME] [--threatdb-password THREATDB_PASSWORD] [--threatdb-token THREATDB_TOKEN]
179
- [--privado-json PRIVADO_JSON] [--server] [--server-host SERVER_HOST] [--server-port SERVER_PORT] [--cdxgen-server CDXGEN_SERVER] [-v]
180
-
181
- Fully open-source security and license audit for application dependencies and container images based on known vulnerabilities and advisories.
179
+ usage: cli.py [-h] [--no-banner] [--cache] [--csaf] [--sync] [--suggest]
180
+ [--no-suggest] [--risk-audit] [--private-ns PRIVATE_NS]
181
+ [-t PROJECT_TYPE] [--bom BOM] [-i SRC_DIR_IMAGE]
182
+ [-o REPORT_FILE] [--reports-dir REPORTS_DIR] [--no-error]
183
+ [--no-license-scan] [--deep] [--no-universal] [--no-vuln-table]
184
+ [--threatdb-server THREATDB_SERVER]
185
+ [--threatdb-username THREATDB_USERNAME]
186
+ [--threatdb-password THREATDB_PASSWORD]
187
+ [--threatdb-token THREATDB_TOKEN] [--privado-json PRIVADO_JSON]
188
+ [--server] [--server-host SERVER_HOST]
189
+ [--server-port SERVER_PORT] [--cdxgen-server CDXGEN_SERVER] [-v]
190
+
191
+ Fully open-source security and license audit for application dependencies and
192
+ container images based on known vulnerabilities and advisories.
182
193
 
183
194
  options:
184
195
  -h, --help show this help message and exit
185
196
  --no-banner Do not display banner
186
- --cache Cache vulnerability information in platform specific user_data_dir
197
+ --cache Cache vulnerability information in platform specific
198
+ user_data_dir
187
199
  --csaf Generate a CSAF
188
- --sync Sync to receive the latest vulnerability data. Should have invoked cache first.
189
- --suggest DEPRECATED: Suggest is the default mode for determining fix version.
200
+ --sync Sync to receive the latest vulnerability data. Should
201
+ have invoked cache first.
202
+ --suggest DEPRECATED: Suggest is the default mode for
203
+ determining fix version.
204
+ --no-suggest Disable suggest mode
190
205
  --risk-audit Perform package risk audit (slow operation). Npm only.
191
206
  --private-ns PRIVATE_NS
192
- Private namespace to use while performing oss risk audit. Private packages should not be available in public registries by default. Comma separated values accepted.
207
+ Private namespace to use while performing oss risk
208
+ audit. Private packages should not be available in
209
+ public registries by default. Comma separated values
210
+ accepted.
193
211
  -t PROJECT_TYPE, --type PROJECT_TYPE
194
212
  Override project type if auto-detection is incorrect
195
- --bom BOM Examine using the given Software Bill-of-Materials (SBoM) file in CycloneDX format. Use cdxgen command to produce one.
213
+ --bom BOM Examine using the given Software Bill-of-Materials
214
+ (SBoM) file in CycloneDX format. Use cdxgen command to
215
+ produce one.
196
216
  -i SRC_DIR_IMAGE, --src SRC_DIR_IMAGE
197
217
  Source directory or container image or binary file
198
218
  -o REPORT_FILE, --report_file REPORT_FILE
199
- DEPRECATED. Use reports directory since multiple files are created. Report filename with directory
219
+ DEPRECATED. Use reports directory since multiple files
220
+ are created. Report filename with directory
200
221
  --reports-dir REPORTS_DIR
201
222
  Reports directory
202
223
  --no-error Continue on error to prevent build from breaking
203
- --no-license-scan DEPRECATED: dep-scan does not perform license scanning by default
204
- --deep Perform deep scan by passing this --deep argument to cdxgen. Useful while scanning docker images and OS packages.
205
- --no-universal Depscan would attempt to perform a single universal scan instead of individual scans per language type.
206
- --no-vuln-table Do not print the table with the full list of vulnerabilities. This can help reduce console output.
224
+ --no-license-scan DEPRECATED: dep-scan does not perform license scanning
225
+ by default
226
+ --deep Perform deep scan by passing this --deep argument to
227
+ cdxgen. Useful while scanning docker images and OS
228
+ packages.
229
+ --no-universal Depscan would attempt to perform a single universal
230
+ scan instead of individual scans per language type.
231
+ --no-vuln-table Do not print the table with the full list of
232
+ vulnerabilities. This can help reduce console output.
207
233
  --threatdb-server THREATDB_SERVER
208
234
  ThreatDB server url. Eg: https://api.sbom.cx
209
235
  --threatdb-username THREATDB_USERNAME
@@ -213,7 +239,10 @@ options:
213
239
  --threatdb-token THREATDB_TOKEN
214
240
  ThreatDB token for token based submission
215
241
  --privado-json PRIVADO_JSON
216
- Optional: Enrich the VEX report with information from privado.ai json report. cdxgen can process and include privado info automatically so this argument is usually not required.
242
+ Optional: Enrich the VEX report with information from
243
+ privado.ai json report. cdxgen can process and include
244
+ privado info automatically so this argument is usually
245
+ not required.
217
246
  --server Run depscan as a server
218
247
  --server-host SERVER_HOST
219
248
  depscan server host
@@ -343,9 +372,10 @@ The following environment variables can be used to customise the behaviour.
343
372
 
344
373
  ## GitHub Security Advisory
345
374
 
346
- To download security advisories from GitHub, a personal access token with the following scope is necessary.
375
+ To download security advisories from GitHub, a personal access token with minimal permissions is necessary.
347
376
 
348
- - read:packages
377
+ - Fine-grained token: Grant no permissions and select the following for repository access: `Public Repositories (read-only)`
378
+ - Token (classic): Grant no permissions
349
379
 
350
380
  ```bash
351
381
  export GITHUB_TOKEN="<PAT token>"
@@ -139,36 +139,60 @@ depscan --src $PWD --reports-dir $PWD/reports
139
139
  Full list of options are below:
140
140
 
141
141
  ```bash
142
- usage: depscan [-h] [--no-banner] [--cache] [--csaf] [--sync] [--suggest] [--risk-audit] [--private-ns PRIVATE_NS] [-t PROJECT_TYPE] [--bom BOM] [-i SRC_DIR_IMAGE] [-o REPORT_FILE] [--reports-dir REPORTS_DIR] [--no-error]
143
- [--no-license-scan] [--deep] [--no-universal] [--no-vuln-table] [--threatdb-server THREATDB_SERVER] [--threatdb-username THREATDB_USERNAME] [--threatdb-password THREATDB_PASSWORD] [--threatdb-token THREATDB_TOKEN]
144
- [--privado-json PRIVADO_JSON] [--server] [--server-host SERVER_HOST] [--server-port SERVER_PORT] [--cdxgen-server CDXGEN_SERVER] [-v]
145
-
146
- Fully open-source security and license audit for application dependencies and container images based on known vulnerabilities and advisories.
142
+ usage: cli.py [-h] [--no-banner] [--cache] [--csaf] [--sync] [--suggest]
143
+ [--no-suggest] [--risk-audit] [--private-ns PRIVATE_NS]
144
+ [-t PROJECT_TYPE] [--bom BOM] [-i SRC_DIR_IMAGE]
145
+ [-o REPORT_FILE] [--reports-dir REPORTS_DIR] [--no-error]
146
+ [--no-license-scan] [--deep] [--no-universal] [--no-vuln-table]
147
+ [--threatdb-server THREATDB_SERVER]
148
+ [--threatdb-username THREATDB_USERNAME]
149
+ [--threatdb-password THREATDB_PASSWORD]
150
+ [--threatdb-token THREATDB_TOKEN] [--privado-json PRIVADO_JSON]
151
+ [--server] [--server-host SERVER_HOST]
152
+ [--server-port SERVER_PORT] [--cdxgen-server CDXGEN_SERVER] [-v]
153
+
154
+ Fully open-source security and license audit for application dependencies and
155
+ container images based on known vulnerabilities and advisories.
147
156
 
148
157
  options:
149
158
  -h, --help show this help message and exit
150
159
  --no-banner Do not display banner
151
- --cache Cache vulnerability information in platform specific user_data_dir
160
+ --cache Cache vulnerability information in platform specific
161
+ user_data_dir
152
162
  --csaf Generate a CSAF
153
- --sync Sync to receive the latest vulnerability data. Should have invoked cache first.
154
- --suggest DEPRECATED: Suggest is the default mode for determining fix version.
163
+ --sync Sync to receive the latest vulnerability data. Should
164
+ have invoked cache first.
165
+ --suggest DEPRECATED: Suggest is the default mode for
166
+ determining fix version.
167
+ --no-suggest Disable suggest mode
155
168
  --risk-audit Perform package risk audit (slow operation). Npm only.
156
169
  --private-ns PRIVATE_NS
157
- Private namespace to use while performing oss risk audit. Private packages should not be available in public registries by default. Comma separated values accepted.
170
+ Private namespace to use while performing oss risk
171
+ audit. Private packages should not be available in
172
+ public registries by default. Comma separated values
173
+ accepted.
158
174
  -t PROJECT_TYPE, --type PROJECT_TYPE
159
175
  Override project type if auto-detection is incorrect
160
- --bom BOM Examine using the given Software Bill-of-Materials (SBoM) file in CycloneDX format. Use cdxgen command to produce one.
176
+ --bom BOM Examine using the given Software Bill-of-Materials
177
+ (SBoM) file in CycloneDX format. Use cdxgen command to
178
+ produce one.
161
179
  -i SRC_DIR_IMAGE, --src SRC_DIR_IMAGE
162
180
  Source directory or container image or binary file
163
181
  -o REPORT_FILE, --report_file REPORT_FILE
164
- DEPRECATED. Use reports directory since multiple files are created. Report filename with directory
182
+ DEPRECATED. Use reports directory since multiple files
183
+ are created. Report filename with directory
165
184
  --reports-dir REPORTS_DIR
166
185
  Reports directory
167
186
  --no-error Continue on error to prevent build from breaking
168
- --no-license-scan DEPRECATED: dep-scan does not perform license scanning by default
169
- --deep Perform deep scan by passing this --deep argument to cdxgen. Useful while scanning docker images and OS packages.
170
- --no-universal Depscan would attempt to perform a single universal scan instead of individual scans per language type.
171
- --no-vuln-table Do not print the table with the full list of vulnerabilities. This can help reduce console output.
187
+ --no-license-scan DEPRECATED: dep-scan does not perform license scanning
188
+ by default
189
+ --deep Perform deep scan by passing this --deep argument to
190
+ cdxgen. Useful while scanning docker images and OS
191
+ packages.
192
+ --no-universal Depscan would attempt to perform a single universal
193
+ scan instead of individual scans per language type.
194
+ --no-vuln-table Do not print the table with the full list of
195
+ vulnerabilities. This can help reduce console output.
172
196
  --threatdb-server THREATDB_SERVER
173
197
  ThreatDB server url. Eg: https://api.sbom.cx
174
198
  --threatdb-username THREATDB_USERNAME
@@ -178,7 +202,10 @@ options:
178
202
  --threatdb-token THREATDB_TOKEN
179
203
  ThreatDB token for token based submission
180
204
  --privado-json PRIVADO_JSON
181
- Optional: Enrich the VEX report with information from privado.ai json report. cdxgen can process and include privado info automatically so this argument is usually not required.
205
+ Optional: Enrich the VEX report with information from
206
+ privado.ai json report. cdxgen can process and include
207
+ privado info automatically so this argument is usually
208
+ not required.
182
209
  --server Run depscan as a server
183
210
  --server-host SERVER_HOST
184
211
  depscan server host
@@ -308,9 +335,10 @@ The following environment variables can be used to customise the behaviour.
308
335
 
309
336
  ## GitHub Security Advisory
310
337
 
311
- To download security advisories from GitHub, a personal access token with the following scope is necessary.
338
+ To download security advisories from GitHub, a personal access token with minimal permissions is necessary.
312
339
 
313
- - read:packages
340
+ - Fine-grained token: Grant no permissions and select the following for repository access: `Public Repositories (read-only)`
341
+ - Token (classic): Grant no permissions
314
342
 
315
343
  ```bash
316
344
  export GITHUB_TOKEN="<PAT token>"
@@ -20,6 +20,7 @@ from vdb.lib.utils import parse_purl
20
20
 
21
21
  import oras.client
22
22
 
23
+ from depscan.lib import privado, utils, github
23
24
  from depscan.lib.csaf import export_csaf, write_toml
24
25
  from depscan.lib import privado, utils
25
26
  from depscan.lib.analysis import (
@@ -114,6 +115,12 @@ def build_args():
114
115
  help="DEPRECATED: Suggest is the default mode for determining fix "
115
116
  "version.",
116
117
  )
118
+ parser.add_argument(
119
+ "--no-suggest",
120
+ action="store_false",
121
+ dest="suggest",
122
+ help="Disable suggest mode",
123
+ )
117
124
  parser.add_argument(
118
125
  "--risk-audit",
119
126
  action="store_true",
@@ -791,8 +798,20 @@ def main():
791
798
  )
792
799
 
793
800
  sources_list = [OSVSource(), NvdSource()]
794
- if os.environ.get("GITHUB_TOKEN"):
795
- sources_list.insert(0, GitHubSource())
801
+ github_token = os.environ.get("GITHUB_TOKEN")
802
+ if github_token:
803
+ github_client = github.GitHub(github_token)
804
+
805
+ if not github_client.can_authenticate():
806
+ LOG.error("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")
807
+ else:
808
+ sources_list.insert(0, GitHubSource())
809
+ scopes = github_client.get_token_scopes()
810
+ if not scopes is None and len(scopes) > 0:
811
+ LOG.warning(
812
+ "The GitHub personal access token was granted more permissions than is necessary for depscan to operate, including the scopes of: %s. It is recommended to use a dedicated token with only the minimum scope necesary for depscan to operate. Please see: https://github.com/owasp-dep-scan/dep-scan#github-security-advisory",
813
+ ', '.join([scope for scope in scopes])
814
+ )
796
815
  if run_cacher:
797
816
  LOG.debug(
798
817
  "About to download vdb from %s. This might take a while ...",
@@ -804,6 +823,7 @@ def main():
804
823
  )
805
824
  LOG.debug("VDB data is stored at: %s", paths_list)
806
825
  run_cacher = False
826
+ db = db_lib.get()
807
827
  elif args.sync:
808
828
  for s in sources_list:
809
829
  LOG.debug("Syncing %s", s.__class__.__name__)
@@ -823,7 +843,7 @@ def main():
823
843
  new_res = []
824
844
  for r in results:
825
845
  new_res.append(r.to_dict())
826
- export_csaf(new_res, src_dir, reports_dir)
846
+ export_csaf(new_res, src_dir, reports_dir, bom_file)
827
847
  # Summarise and print results
828
848
  summarise(
829
849
  project_type,
@@ -1111,39 +1111,42 @@ TOML_TEMPLATE = {
1111
1111
  }
1112
1112
 
1113
1113
  ref_map = {
1114
+ r"(?P<org>[^\s./]+).(?:com|org)/(?:[\S]+)?/(?P<id>("
1115
+ r"?:ghsa|ntap|rhsa|rhba|zdi|dsa|cisco|intel)-?[\w\d\-:]+)": "Advisory",
1114
1116
  r"cve-[0-9]{4,}-[0-9]{4,}$": "CVE Record",
1115
1117
  r"(?<=bugzilla.)\S+(?=.\w{3}/show_bug.cgi\?)": "Bugzilla",
1116
- r"https://github.com/([\w\d\-.]+/[\w\d\-.]+/security/)?advisories": "GitHub Advisory",
1117
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/pull/\d+": "GitHub Pull Request",
1118
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/commit": "GitHub Commit",
1119
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/release": "GitHub Repository "
1120
- "Release",
1121
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/issues/?": "GitHub Issue",
1122
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/blob": "GitHub Blob Reference",
1123
- r"https://github.com/[\w\d\-.]+/[\w\d\-.]+/?$": "GitHub Repository",
1124
- "https://gist.github.com": "GitHub Gist",
1125
- r"https://github.com/": "GitHub Other",
1126
- r"https://access.redhat.com/errata/rhba-\d{4}:\d{4}": "Red Hat Bug Fix "
1127
- "Advisory",
1128
- r"https://access.redhat.com/errata/rhsa-\d{4}:\d{4}": "Red Hat Security "
1129
- "Advisory",
1130
- r"(?<=CiscoSecurityAdvisory/)[\w\d\-]+": "Cisco Security Advisory",
1131
- "https://www.npmjs.com/advisories/": "NPM Advisory",
1132
- r"https://www.npmjs.com/package/@?\w+/?\w+": "NPM Package Page",
1133
- "https://www.oracle.com/security-alerts": "Oracle Security Alert",
1134
- "https://security.netapp.com/advisory": "NetApp Security Advisory",
1135
- "https://security.snyk.io/vuln": "Snyk Vulnerability Database Entry",
1136
- "https://snyk.io/vuln/": "Snyk Vulnerability Database Entry",
1137
- "https://www.debian.org/security": "Debian Security Advisory",
1138
- "https://security.gentoo.org/glsa": "Gentoo Security Advisory",
1139
- ".+advisory.?": "Advisory",
1118
+ r"github.com/[\w\-.]+/[\w\-.]+/pull/\d+": "GitHub Pull Request",
1119
+ r"github.com/[\w\-.]+/[\w\-.]+/release": "GitHub Repository Release",
1120
+ r"(github|bitbucket|chromium)(?:.com|.org)/([\w\-.]+)/([\w\-.]+)/issues/("
1121
+ r"?:detail\?id=)?(\d+)": "Issue",
1122
+ r"github.com/[\w\-.]+/[\w\-.]+/blob": "GitHub Blob Reference",
1123
+ r"github.com/[\w\-.]+/[\w\-.]+/commit": "GitHub Commit",
1124
+ r"github.com/[\w\-.]+/[\w\-.]+/?$": "GitHub Repository",
1125
+ "gist.github.com": "GitHub Gist",
1126
+ r"github.com/": "GitHub Other",
1127
+ "npmjs.com/advisories/": "NPM Advisory",
1128
+ r"npmjs.com/package/@?\w+/?\w+": "NPM Package Page",
1129
+ "oracle.com/security-alerts": "Oracle Security Alert",
1130
+ "security.snyk.io/vuln|https://snyk.io/vuln/": "Snyk Vulnerability "
1131
+ "Database Entry",
1132
+ "security.gentoo.org/glsa": "Advisory",
1133
+ r"usn.ubuntu.com/[\d\-]+|ubuntu.com/security/notices/USN\-[\d\-]+":
1134
+ "Ubuntu Security Notice",
1135
+ r"lists.[\w\-]+.org/[\S]+announce": "Mailing List Announcement",
1136
+ r"lists.[\w\-]+.org/": "Mailing List Other",
1137
+ "blog": "Blog Post",
1138
+ r"bitbucket.org/[^\s/]+/[^\s/]+/?(?!.)": "Bitbucket Repository",
1139
+ r"bitbucket.org/[^\s/]+/[^\s/]+/commits": "Bitbucket Commit",
1140
+ r"bitbucket.org/[^\s/]+/[^\s/]+/issues/\d+(/)?": "Bitbucket Issue",
1141
+ r"bitbucket.org/[^\s/]+/[^\s/]+/wiki/": "Bitbucket Wiki Entry",
1142
+ r"https://vuldb.com/\?id.\d+": "VulDB Entry",
1140
1143
  }
1141
-
1142
1144
  sorted_ref_map = sorted(ref_map.items(), key=lambda x: len(x[0]), reverse=True)
1143
1145
  sorted_ref_map = dict(sorted_ref_map)
1144
1146
 
1145
1147
  compiled_patterns = {
1146
- re.compile(pattern): value for pattern, value in sorted_ref_map.items()
1148
+ re.compile(pattern, re.IGNORECASE): value for pattern, value in
1149
+ sorted_ref_map.items()
1147
1150
  }
1148
1151
 
1149
1152
 
@@ -1320,78 +1323,68 @@ def format_references(ref):
1320
1323
  """
1321
1324
  fmt_refs = [{"summary": get_ref_summary(r), "url": r} for r in ref]
1322
1325
  ids = []
1323
- refs = []
1324
- github_advisory_regex = re.compile(r"(GHSA-\w{4}-\w{4}-\w{4}$)")
1325
- github_issue_regex = re.compile(
1326
- r"(?<=https://github.com/)(?P<owner>["
1327
- r"^\s/]+)/(?P<repo>[^\s/]+)/issues/("
1328
- r"?P<id>\d+)"
1326
+ issues_regex = re.compile(
1327
+ r"(?P<host>github|bitbucket|chromium)(?:.com|.org)/(?P<owner>["
1328
+ r"\w\-.]+)/(?P<repo>[\w\-.]+)/issues/(?:detail\?id=)?(?P<id>\d+)",
1329
+ re.IGNORECASE
1329
1330
  )
1331
+ advisory_regex = re.compile(
1332
+ r"(?P<org>[^\s/.]+).(?:com|org)/(?:\S+/)*/?(?P<id>[\w\-:]+)",
1333
+ re.IGNORECASE)
1330
1334
  bugzilla_regex = re.compile(
1331
- r"(?<=bugzilla.)(?P<owner>[^\s]+)\.\w{3}/show_bug.cgi\?id=(?P<id>\S+)"
1335
+ r"(?<=bugzilla.)(?P<owner>\S+)\.\w{3}/show_bug.cgi\?id=(?P<id>"
1336
+ r"\S+)", re.IGNORECASE)
1337
+ usn_regex = re.compile(
1338
+ r"(?<=usn.ubuntu.com/)[\d\-]+|(?<=ubuntu.com/security/notices/USN-)["
1339
+ r"\d\-]+", re.IGNORECASE
1332
1340
  )
1333
- redhat_advisory_regex = re.compile(r"(RH[BS]A-\d{4}:\d+)")
1334
- cisco_regex = re.compile(r"(?<=CiscoSecurityAdvisory/)[\w\d\-]+")
1335
- id_types = [
1336
- "GitHub Advisory",
1337
- "GitHub Issue",
1338
- "Bugzilla",
1339
- "Cisco Security Advisory",
1340
- "Red Hat Security Advisory",
1341
- "Red Hat Bug Fix Advisory",
1342
- ]
1341
+ id_types = ["Advisory", "Issue", "Ubuntu Security Notice", "Bugzilla"]
1343
1342
  parse = [i for i in fmt_refs if i.get("summary") in id_types]
1343
+ refs = [i for i in fmt_refs if i.get("summary") not in id_types]
1344
1344
  for reference in parse:
1345
- r = reference["url"]
1345
+ url = reference["url"]
1346
1346
  summary = reference["summary"]
1347
- if summary == "GitHub Advisory":
1348
- if gha := re.search(github_advisory_regex, r):
1349
- ids.append(
1350
- {
1351
- "system_name": summary,
1352
- "text": gha.group(0),
1353
- }
1347
+ if summary == "Advisory":
1348
+ url = url.replace("glsa/", "glsa-")
1349
+ if adv := re.search(advisory_regex, url):
1350
+ system_name = (
1351
+ (adv["org"].capitalize() + " Advisory")
1352
+ .replace("Redhat", "Red Hat")
1353
+ .replace("Zerodayinitiative", "Zero Day Initiative")
1354
+ .replace("Github", "GitHub")
1355
+ .replace("Netapp", "NetApp")
1354
1356
  )
1355
- elif summary == "GitHub Issue":
1356
- if issue := re.search(github_issue_regex, r):
1357
- ids.append(
1358
- {
1359
- "system_name": f'GitHub Issue [{issue.group("owner")}'
1360
- f'/{issue.group("repo")}]',
1361
- "text": issue.group("id"),
1362
- }
1363
- )
1364
- elif summary == "Bugzilla":
1365
- if bugzilla := re.search(bugzilla_regex, r):
1366
- new_id = {
1367
- "system_name": f"{bugzilla.group('owner').capitalize()} Bugzilla ID",
1368
- "text": bugzilla.group("id"),
1357
+ ids.append({"system_name": system_name, "text": adv["id"]})
1358
+ summary = system_name
1359
+ elif issue := re.search(issues_regex, url):
1360
+ summary = (
1361
+ issue["host"].capitalize().replace("Github", "GitHub")
1362
+ + " Issue"
1363
+ )
1364
+ ids.append(
1365
+ {
1366
+ "system_name": summary
1367
+ + (
1368
+ f" [{issue['owner']}/{issue['repo']}]"
1369
+ if issue["owner"] != "p"
1370
+ else f" [{issue['repo']}]"
1371
+ ),
1372
+ "text": issue["id"],
1369
1373
  }
1370
- if new_id["system_name"] == "Redhat Bugzilla ID":
1371
- new_id["system_name"] = "Red Hat Bugzilla ID"
1372
- ids.append(new_id)
1373
- elif summary == "Cisco Security Advisory":
1374
- if csa := re.search(cisco_regex, r):
1375
- ids.append(
1376
- {
1377
- "system_name": summary,
1378
- "text": csa.group(0),
1379
- }
1380
- )
1381
- elif summary in [
1382
- "Red Hat Security Advisory",
1383
- "Red Hat Bug Fix Advisory",
1384
- ]:
1385
- if bugzilla_id := re.search(redhat_advisory_regex, r):
1386
- ids.append(
1387
- {
1388
- "system_name": summary,
1389
- "text": bugzilla_id.group(0),
1390
- }
1391
- )
1392
- new_ids = {(id["system_name"], id["text"]) for id in ids}
1393
- ids = [{"system_name": id[0], "text": id[1]} for id in new_ids]
1394
- return ids, fmt_refs
1374
+ )
1375
+ elif bugzilla := re.search(bugzilla_regex, url):
1376
+ system_name = f"{bugzilla['owner'].capitalize()} Bugzilla"
1377
+ system_name = system_name.replace("Redhat", "Red Hat")
1378
+ ids.append(
1379
+ {"system_name": f"{system_name} ID", "text": bugzilla["id"]}
1380
+ )
1381
+ summary = system_name
1382
+ elif usn := re.search(usn_regex, url):
1383
+ ids.append({"system_name": summary, "text": f"USN-{usn[0]}"})
1384
+ refs.append({"summary": summary, "url": url})
1385
+ new_ids = {(idx["system_name"], idx["text"]) for idx in ids}
1386
+ ids = [{"system_name": idx[0], "text": idx[1]} for idx in new_ids]
1387
+ return ids, refs
1395
1388
 
1396
1389
 
1397
1390
  def get_ref_summary(url):
@@ -1412,7 +1405,7 @@ def get_ref_summary(url):
1412
1405
  (
1413
1406
  value
1414
1407
  for pattern, value in compiled_patterns.items()
1415
- if pattern.search(url.lower())
1408
+ if pattern.search(url)
1416
1409
  ),
1417
1410
  "Other",
1418
1411
  )
@@ -1468,13 +1461,19 @@ def parse_revision_history(tracking):
1468
1461
  except AttributeError:
1469
1462
  LOG.warning("Your dates don't appear to be in ISO format.")
1470
1463
  if status == "final" and (not hx or len(hx) == 0):
1464
+ choose_date = max(
1465
+ tracking.get("initial_release_date"),
1466
+ tracking.get("current_release_date"),
1467
+ )
1471
1468
  hx.append(
1472
1469
  {
1473
- "date": tracking["initial_release_date"],
1470
+ "date": choose_date,
1474
1471
  "number": "1",
1475
1472
  "summary": "Initial",
1476
1473
  }
1477
1474
  )
1475
+ tracking["current_release_date"] = choose_date
1476
+ tracking["initial_release_date"] = choose_date
1478
1477
  elif status == "final":
1479
1478
  hx = sorted(hx, key=lambda x: x["number"])
1480
1479
  tracking["initial_release_date"] = hx[0]["date"]
@@ -1587,8 +1586,8 @@ def toml_compatibility(metadata):
1587
1586
  Applies any changes to the formatting of the TOML after a depscan
1588
1587
  minor or patch update
1589
1588
  """
1590
- # The 4.5.0 TOML referenced revision_history as revision
1591
- if metadata["depscan_version"] < "4.5.1":
1589
+ # The 4.3.0 TOML referenced revision_history as revision
1590
+ if metadata["depscan_version"] < "4.3.1":
1592
1591
  metadata["tracking"]["revision_history"] = metadata["tracking"].get(
1593
1592
  "revision"
1594
1593
  )
@@ -1597,7 +1596,7 @@ def toml_compatibility(metadata):
1597
1596
  return metadata
1598
1597
 
1599
1598
 
1600
- def export_csaf(results, src_dir, reports_dir):
1599
+ def export_csaf(results, src_dir, reports_dir, bom_file):
1601
1600
  """
1602
1601
  Generates a CSAF JSON template from the given results.
1603
1602
 
@@ -1605,6 +1604,7 @@ def export_csaf(results, src_dir, reports_dir):
1605
1604
  results (list): A list of results obtained from the analysis.
1606
1605
  src_dir (str): The source directory.
1607
1606
  reports_dir (str): The reports directory.
1607
+ bom_file (str): The BOM file path
1608
1608
 
1609
1609
  Returns:
1610
1610
  None
@@ -1633,6 +1633,13 @@ def export_csaf(results, src_dir, reports_dir):
1633
1633
  + severity_ref[agg_score[0]][1:].lower()
1634
1634
  )
1635
1635
  template["document"]["aggregate_severity"]["text"] = agg_severity
1636
+ if not template.get("product_tree"):
1637
+ [template["product_tree"], extra_ref] = import_root_component(
1638
+ bom_file)
1639
+ if extra_ref and template["document"].get("references"):
1640
+ template["document"]["references"].append(extra_ref)
1641
+ elif extra_ref:
1642
+ template["document"]["references"] = [extra_ref]
1636
1643
  new_results = cleanup_dict(template)
1637
1644
  # CSAF forbids revision entries unless the status is final, but requires
1638
1645
  # this to be here nonetheless
@@ -1744,3 +1751,43 @@ def cleanup_dict(d):
1744
1751
  if entry:
1745
1752
  new_dict[key] = entry
1746
1753
  return new_dict
1754
+
1755
+
1756
+ def import_root_component(bom_file):
1757
+ """
1758
+ Imports the root component from the given bom file into the csaf
1759
+ """
1760
+ with open(bom_file, "r") as f:
1761
+ bom = json.load(f)
1762
+
1763
+ refs = []
1764
+ product_tree = {}
1765
+
1766
+ if component := bom["metadata"].get("component"):
1767
+ product_tree = {
1768
+ "full_product_names": [
1769
+ {
1770
+ "name": component.get("name"),
1771
+ "product_id": f"{component.get('name')}:"
1772
+ f"{component.get('version')}",
1773
+ "product_identification_helper": {
1774
+ "purl": component.get("purl"),
1775
+ },
1776
+ }
1777
+ ]
1778
+ }
1779
+ if external_references := component.get("externalReferences"):
1780
+ refs.extend(
1781
+ {
1782
+ "summary": r.get("type"),
1783
+ "url": r.get("url"),
1784
+ }
1785
+ for r in external_references
1786
+ )
1787
+ if product_tree:
1788
+ LOG.info("Successfully imported root component into the product tree.")
1789
+ else:
1790
+ LOG.info("Unable to import root component for product tree, "
1791
+ "so product tree will not be included.")
1792
+
1793
+ return product_tree, refs