Skip to content

Commit f7b9499

Browse files
committed
add support for pip-audit
1 parent 9b40888 commit f7b9499

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

docs/8-CODEREVIEW_UTILS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
| Node | [npm audit](https://docs.npmjs.com/cli/v9/commands/npm-audit) when NPM is used as package manager ||
1616
| Node | [yarn audit](https://classic.yarnpkg.com/lang/en/docs/cli/audit/) when YARN is used as package manager ||
1717
| .NET | [dotnet package list](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-package-list) command ||
18+
| Python | [pip-audit](https://pypi.org/project/pip-audit/) ||
1819
| Cross technologies | [OWASP Dependency Check](https://owasp.org/www-project-dependency-check/) ||
1920
| Cross technologies | [osv-scanner](https://github.com/google/osv-scanner) ||
2021
| JavaScript | [retire.js](https://github.com/retirejs/retire.js/) ||

scripts/generate-report-vulnerable-components.py

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- retire.js
2626
- npm audit
2727
- yarn audit
28+
- pip-audit
2829
2930
[i] Identifiers mapping:
3031
@@ -34,6 +35,7 @@
3435
- retire.js => retirejs
3536
- npm audit => npm-audit
3637
- yarn audit => yarn-audit
38+
- pip-audit => pip-audit
3739
3840
[i] Command lines to generate the data file used by this script:
3941
@@ -56,12 +58,15 @@
5658
5759
yarn audit
5860
=> yarn audit --json > report.json
61+
62+
pip-audit
63+
=> pip-audit --requirement requirements.txt --format json --output report.json
5964
"""
6065

6166
ENTRY_MAX_LENGTH_FOR_DISPLAY = 30
6267
DEFAULT_ENCODING = "utf-8"
6368
VULN_IDS_FILE = "global-cve-ghsa.txt"
64-
SCA_TOOLS_IDENTIFIERS = ["owasp-dependency-check", "dotnet-package-list", "osv-scanner", "retirejs", "npm-audit", "yarn-audit"]
69+
SCA_TOOLS_IDENTIFIERS = ["owasp-dependency-check", "dotnet-package-list", "osv-scanner", "retirejs", "npm-audit", "yarn-audit", "pip-audit"]
6570
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
6671
REQ_SESSION = requests.session()
6772
# Needed for ENISA API otherwise an HTTP 403 is received
@@ -77,6 +82,8 @@
7782
# https://deps.dev/_/s/maven/p/com.thoughtworks.xstream%3Axstream/v/1.4.10
7883
# https://deps.dev/_/s/nuget/p/system.text.json/v/9.0.6
7984
DEPSDEV_URL_TPL = "https://deps.dev/_/s/%s/p/%s/v/%s"
85+
# KEY is the package manager official name and VALUE if the corresponding name used by deps.dev
86+
DEPSDEV_PACKAGE_MANAGER_MAPPING = {"pip": "pypi"}
8087

8188

8289
@functools.total_ordering
@@ -188,6 +195,9 @@ def find_fix_exists_for_osv_scanner_vuln(vulnerability):
188195

189196

190197
def find_if_false_positive(package_name, package_version, package_manager, cves_id_list):
198+
depdev_package_manager_name = package_manager
199+
if package_manager in DEPSDEV_PACKAGE_MANAGER_MAPPING:
200+
depdev_package_manager_name = DEPSDEV_PACKAGE_MANAGER_MAPPING[package_manager]
191201
# When the version contain a range (it is the case for NPM) then I consider that
192202
# I cannot perform the validation against DEPS.DEV
193203
if len(re.findall(r'[\<\>|\*]+', package_version)) > 0 or " - " in package_version:
@@ -200,7 +210,7 @@ def find_if_false_positive(package_name, package_version, package_manager, cves_
200210
try:
201211
package_name_adapted = package_name.replace("/", ":") # on deps.dev the group name and the artefact name are separated by ":"
202212
package_name_adapted = encode_package_name(package_name_adapted)
203-
package_depsdev_url = DEPSDEV_URL_TPL % (package_manager, package_name_adapted, package_version)
213+
package_depsdev_url = DEPSDEV_URL_TPL % (depdev_package_manager_name, package_name_adapted, package_version)
204214
response = REQ_SESSION.get(package_depsdev_url, timeout=REQ_TIMEOUT)
205215
if response.status_code == 200:
206216
cves_id_found = []
@@ -521,6 +531,46 @@ def load_data_from_retirejs(json_data):
521531
return vulnerable_components
522532

523533

534+
def load_data_from_pip_audit(json_data):
535+
vulnerable_components = []
536+
package_manager_name = "pip"
537+
for dep in json_data["dependencies"]:
538+
vulns = dep["vulns"]
539+
component_name = dep["name"]
540+
component_version = dep["version"]
541+
for vuln in vulns:
542+
ghsa = vuln["id"]
543+
cves = vuln["aliases"]
544+
fixed_versions = vuln["fix_versions"]
545+
if len(fixed_versions) > 0:
546+
extra = "Fixed in versions " + ",".join(fixed_versions)
547+
else:
548+
extra = ""
549+
# As the CVSS score is not provided then retrieve
550+
# the severity and the score using the CVE ID (take first CVE as the reference)
551+
cve_id = cves[0]
552+
data = find_cve_severity([cve_id])
553+
if data[cve_id] is not None:
554+
cvss_score = data[cve_id][0]
555+
severity = data[cve_id][1]
556+
else:
557+
cvss_score = 0
558+
severity = "NA"
559+
vulnerable_component = VulnerableComponentProperties()
560+
vulnerable_component.package_name = component_name
561+
vulnerable_component.version = component_version
562+
vulnerable_component.file_name = "-"
563+
vulnerable_component.ghsa_ids = ghsa
564+
vulnerable_component.cve_ids = CVE_GHSA_CWE_SEPARATOR_CHAR.join(cves)
565+
vulnerable_component.cwe_ids = ""
566+
vulnerable_component.cvss_score = cvss_score
567+
vulnerable_component.severity = severity
568+
vulnerable_component.extra_information = extra
569+
vulnerable_component.package_manager = package_manager_name
570+
vulnerable_components.append(vulnerable_component)
571+
return vulnerable_components
572+
573+
524574
def enrich_with_false_positive_marker(vulnerable_components):
525575
for vulnerable_component in vulnerable_components:
526576
cves_id_list = vulnerable_component.cve_ids.split(CVE_GHSA_CWE_SEPARATOR_CHAR)
@@ -557,6 +607,8 @@ def load_information(input_data_file, sca_tool_id):
557607
vulnerable_components = load_data_from_npm_audit(components_data)
558608
elif sca_tool_id == "yarn-audit":
559609
vulnerable_components = load_data_from_yarn_audit(components_data)
610+
elif sca_tool_id == "pip-audit":
611+
vulnerable_components = load_data_from_pip_audit(components_data)
560612
else:
561613
raise Exception("SCA tools not supported!")
562614
return vulnerable_components

0 commit comments

Comments
 (0)