Skip to content

Commit

Permalink
Allow alias IDs to be toggled for JSON output; updated documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pboulos committed Jan 10, 2024
1 parent 10315d3 commit bd41f64
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 43 deletions.
35 changes: 17 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ python -m pip_audit --help
<!-- @begin-pip-audit-help@ -->
```
usage: pip-audit [-h] [-V] [-l] [-r REQUIREMENT] [-f FORMAT] [-s SERVICE] [-d]
[-S] [--desc [{on,off,auto}]] [--cache-dir CACHE_DIR]
[--progress-spinner {on,off}] [--timeout TIMEOUT]
[--path PATH] [-v] [--fix] [--require-hashes]
[--index-url INDEX_URL] [--extra-index-url URL]
[--skip-editable] [--no-deps] [-o FILE] [--ignore-vuln ID]
[--disable-pip]
[-S] [--desc [{on,off,auto}]] [--aliases [{on,off,auto}]]
[--cache-dir CACHE_DIR] [--progress-spinner {on,off}]
[--timeout TIMEOUT] [--path PATH] [-v] [--fix]
[--require-hashes] [--index-url INDEX_URL]
[--extra-index-url URL] [--skip-editable] [--no-deps]
[-o FILE] [--ignore-vuln ID] [--disable-pip]
[project_path]

audit the Python environment for dependencies with known vulnerabilities
Expand Down Expand Up @@ -173,9 +173,8 @@ optional arguments:
formats. (default: auto)
--aliases [{on,off,auto}]
includes alias IDs for each vulnerability; `auto`
defaults to `off` for the `column` and `markdown`
formats. This flag has no effect on the
`cyclonedx-json`, `cyclonedx-xml`, and `json`
defaults to `on` for the `json` format. This flag has
no effect on the `cyclonedx-json` or `cyclonedx-xml`
formats. (default: auto)
--cache-dir CACHE_DIR
the directory to use as an HTTP cache for PyPI; uses
Expand Down Expand Up @@ -285,9 +284,9 @@ Audit dependencies including aliases:
$ pip-audit --aliases
Found 2 known vulnerabilities in 1 package
Name Version ID Fix Versions Aliases
---- ------- -------------- ------------ ------------------------------------
Flask 0.5 PYSEC-2019-179 1.0 CVE-2019-1010083,GHSA-5wv5-4vpf-pj6m
Flask 0.5 PYSEC-2018-66 0.12.3 CVE-2018-1000656,GHSA-562c-5r94-xh97
---- ------- -------------- ------------ -------------------------------------
Flask 0.5 PYSEC-2019-179 1.0 CVE-2019-1010083, GHSA-5wv5-4vpf-pj6m
Flask 0.5 PYSEC-2018-66 0.12.3 CVE-2018-1000656, GHSA-562c-5r94-xh97
```
Audit dependencies including descriptions:
Expand All @@ -311,24 +310,24 @@ Found 2 known vulnerabilities in 1 package
"vulns": [
{
"id": "PYSEC-2019-179",
"fix_versions": [
"1.0"
],
"aliases": [
"CVE-2019-1010083",
"GHSA-5wv5-4vpf-pj6m"
],
"fix_versions": [
"1.0"
],
"description": "The Pallets Project Flask before 1.0 is affected by: unexpected memory usage. The impact is: denial of service. The attack vector is: crafted encoded JSON data. The fixed version is: 1. NOTE: this may overlap CVE-2018-1000656."
},
{
"id": "PYSEC-2018-66",
"fix_versions": [
"0.12.3"
],
"aliases": [
"CVE-2018-1000656",
"GHSA-562c-5r94-xh97"
],
"fix_versions": [
"0.12.3"
],
"description": "The Pallets Project flask version Before 0.12.3 contains a CWE-20: Improper Input Validation vulnerability in flask that can result in Large amount of memory usage possibly leading to denial of service. This attack appear to be exploitable via Attacker provides JSON data in incorrect encoding. This vulnerability appears to have been fixed in 0.12.3. NOTE: this may overlap CVE-2019-1010083."
}
]
Expand Down
4 changes: 1 addition & 3 deletions pip_audit/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def to_format(self, output_desc: bool, output_aliases: bool) -> VulnerabilityFor
if self is OutputFormatChoice.Columns:
return ColumnsFormat(output_desc, output_aliases)
elif self is OutputFormatChoice.Json:
return JsonFormat(output_desc)
return JsonFormat(output_desc, output_aliases)
elif self is OutputFormatChoice.CycloneDxJson:
return CycloneDxFormat(inner_format=CycloneDxFormat.InnerFormat.Json)
elif self is OutputFormatChoice.CycloneDxXml:
Expand Down Expand Up @@ -145,8 +145,6 @@ class VulnerabilityAliasChoice(str, enum.Enum):
Auto = "auto"

def to_bool(self, format_: OutputFormatChoice) -> bool:
if format_ is OutputFormatChoice.Json: # Note: Aliases are always rendered for JSON.
return True
if self is VulnerabilityAliasChoice.On:
return True
elif self is VulnerabilityAliasChoice.Off:
Expand Down
9 changes: 7 additions & 2 deletions pip_audit/_format/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ class JsonFormat(VulnerabilityFormat):
JSON objects.
"""

def __init__(self, output_desc: bool):
def __init__(self, output_desc: bool, output_aliases: bool):
"""
Create a new `JsonFormat`.
`output_desc` is a flag to determine whether descriptions for each vulnerability should be
included in the output as they can be quite long and make the output difficult to read.
`output_aliases` is a flag to determine whether aliases (such as CVEs) for each
vulnerability should be included in the output.
"""
self.output_desc = output_desc
self.output_aliases = output_aliases

@property
def is_manifest(self) -> bool:
Expand Down Expand Up @@ -76,9 +80,10 @@ def _format_dep(
def _format_vuln(self, vuln: service.VulnerabilityResult) -> dict[str, Any]:
vuln_json = {
"id": vuln.id,
"aliases": list(vuln.aliases),
"fix_versions": [str(version) for version in vuln.fix_versions],
}
if self.output_aliases:
vuln_json["aliases"] = list(vuln.aliases)
if self.output_desc:
vuln_json["description"] = vuln.description
return vuln_json
Expand Down
83 changes: 63 additions & 20 deletions test/format/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import pip_audit._format as format


@pytest.mark.parametrize("output_desc", [True, False])
def test_json_manifest(output_desc):
fmt = format.JsonFormat(output_desc)
@pytest.mark.parametrize("output_desc, output_aliases", ([True, False], [True, False]))
def test_json_manifest(output_desc, output_aliases):
fmt = format.JsonFormat(output_desc, output_aliases)

assert fmt.is_manifest


def test_json(vuln_data):
json_format = format.JsonFormat(True)
json_format = format.JsonFormat(True, True)
expected_json = {
"dependencies": [
{
Expand All @@ -22,17 +22,17 @@ def test_json(vuln_data):
"vulns": [
{
"id": "VULN-0",
"aliases": ["CVE-0000-00000"],
"fix_versions": [
"1.1",
"1.4",
],
"aliases": ["CVE-0000-00000"],
"description": "The first vulnerability",
},
{
"id": "VULN-1",
"aliases": ["CVE-0000-00001"],
"fix_versions": ["1.0"],
"aliases": ["CVE-0000-00001"],
"description": "The second vulnerability",
},
],
Expand All @@ -43,8 +43,8 @@ def test_json(vuln_data):
"vulns": [
{
"id": "VULN-2",
"aliases": ["CVE-0000-00002"],
"fix_versions": [],
"aliases": ["CVE-0000-00002"],
"description": "The third vulnerability",
}
],
Expand All @@ -56,7 +56,7 @@ def test_json(vuln_data):


def test_json_no_desc(vuln_data):
json_format = format.JsonFormat(False)
json_format = format.JsonFormat(False, True)
expected_json = {
"dependencies": [
{
Expand All @@ -65,23 +65,66 @@ def test_json_no_desc(vuln_data):
"vulns": [
{
"id": "VULN-0",
"aliases": ["CVE-0000-00000"],
"fix_versions": [
"1.1",
"1.4",
],
"aliases": ["CVE-0000-00000"],
},
{
"id": "VULN-1",
"fix_versions": ["1.0"],
"aliases": ["CVE-0000-00001"],
},
],
},
{
"name": "bar",
"version": "0.1",
"vulns": [
{
"id": "VULN-2",
"fix_versions": [],
"aliases": ["CVE-0000-00002"],
}
],
},
],
"fixes": [],
}
assert json_format.format(vuln_data, list()) == json.dumps(expected_json)


def test_json_no_desc_no_aliases(vuln_data):
json_format = format.JsonFormat(False, False)
expected_json = {
"dependencies": [
{
"name": "foo",
"version": "1.0",
"vulns": [
{
"id": "VULN-0",
"fix_versions": [
"1.1",
"1.4",
],
},
{
"id": "VULN-1",
"fix_versions": ["1.0"],
},
],
},
{
"name": "bar",
"version": "0.1",
"vulns": [{"id": "VULN-2", "aliases": ["CVE-0000-00002"], "fix_versions": []}],
"vulns": [
{
"id": "VULN-2",
"fix_versions": [],
}
],
},
],
"fixes": [],
Expand All @@ -90,7 +133,7 @@ def test_json_no_desc(vuln_data):


def test_json_skipped_dep(vuln_data_skipped_dep):
json_format = format.JsonFormat(False)
json_format = format.JsonFormat(False, True)
expected_json = {
"dependencies": [
{
Expand All @@ -99,11 +142,11 @@ def test_json_skipped_dep(vuln_data_skipped_dep):
"vulns": [
{
"id": "VULN-0",
"aliases": ["CVE-0000-00000"],
"fix_versions": [
"1.1",
"1.4",
],
"aliases": ["CVE-0000-00000"],
},
],
},
Expand All @@ -118,7 +161,7 @@ def test_json_skipped_dep(vuln_data_skipped_dep):


def test_json_fix(vuln_data, fix_data):
json_format = format.JsonFormat(True)
json_format = format.JsonFormat(True, True)
expected_json = {
"dependencies": [
{
Expand All @@ -127,17 +170,17 @@ def test_json_fix(vuln_data, fix_data):
"vulns": [
{
"id": "VULN-0",
"aliases": ["CVE-0000-00000"],
"fix_versions": [
"1.1",
"1.4",
],
"aliases": ["CVE-0000-00000"],
"description": "The first vulnerability",
},
{
"id": "VULN-1",
"aliases": ["CVE-0000-00001"],
"fix_versions": ["1.0"],
"aliases": ["CVE-0000-00001"],
"description": "The second vulnerability",
},
],
Expand All @@ -148,8 +191,8 @@ def test_json_fix(vuln_data, fix_data):
"vulns": [
{
"id": "VULN-2",
"aliases": ["CVE-0000-00002"],
"fix_versions": [],
"aliases": ["CVE-0000-00002"],
"description": "The third vulnerability",
}
],
Expand All @@ -172,7 +215,7 @@ def test_json_fix(vuln_data, fix_data):


def test_json_skipped_fix(vuln_data, skipped_fix_data):
json_format = format.JsonFormat(True)
json_format = format.JsonFormat(True, True)
expected_json = {
"dependencies": [
{
Expand All @@ -181,17 +224,17 @@ def test_json_skipped_fix(vuln_data, skipped_fix_data):
"vulns": [
{
"id": "VULN-0",
"aliases": ["CVE-0000-00000"],
"fix_versions": [
"1.1",
"1.4",
],
"aliases": ["CVE-0000-00000"],
"description": "The first vulnerability",
},
{
"id": "VULN-1",
"aliases": ["CVE-0000-00001"],
"fix_versions": ["1.0"],
"aliases": ["CVE-0000-00001"],
"description": "The second vulnerability",
},
],
Expand All @@ -202,8 +245,8 @@ def test_json_skipped_fix(vuln_data, skipped_fix_data):
"vulns": [
{
"id": "VULN-2",
"aliases": ["CVE-0000-00002"],
"fix_versions": [],
"aliases": ["CVE-0000-00002"],
"description": "The third vulnerability",
}
],
Expand Down

0 comments on commit bd41f64

Please sign in to comment.