Skip to content

Commit

Permalink
cli: allow ignoring specific vulnerability IDs
Browse files Browse the repository at this point in the history
This commit introduces a new flag to pip-audit's CLI (--ignore-vuln)
that takes a string representing a vulnerability id, if any of the
packages scanned detect said vulnerability, it will be ignored in the
final report.

This allows users of pip-audit to ignore certain vulnerabilities that
they may deem not exploitable for whatever reason.

The flag can be used multiple times to ignore multiple vulnerabilities.

Closes #245
  • Loading branch information
Adrian Torres committed May 10, 2022
1 parent 51a0a02 commit 27c2574
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

All versions prior to 0.0.9 are untracked.

## [Unreleased]

### Added

* CLI: The `--ignore-vuln` option has been added, allowing users to
specify vulnerability IDs to ignore during the final report.
([#275](https://github.com/trailofbits/pip-audit/pull/275))

## [2.2.1] - 2022-05-02

### Fixed
Expand Down
26 changes: 24 additions & 2 deletions pip_audit/_cli.py
Expand Up @@ -287,6 +287,14 @@ def _parser() -> argparse.ArgumentParser:
# argparse's default renderer uses __repr__ and produces
# a pretty unpleasant help message.
)
parser.add_argument(
"--ignore-vuln",
type=str,
action="append",
dest="ignore_vulns",
default=[],
help="ignore a specific vulnerability by its PYSEC id",
)
return parser


Expand Down Expand Up @@ -390,6 +398,8 @@ def audit() -> None:
pkg_count = 0
vuln_count = 0
skip_count = 0
vuln_ignore_count = 0
vulns_to_ignore = set(args.ignore_vulns)
for (spec, vulns) in auditor.audit(source):
if spec.is_skipped():
spec = cast(SkippedDependency, spec)
Expand All @@ -401,6 +411,10 @@ def audit() -> None:
else:
spec = cast(ResolvedDependency, spec)
state.update_state(f"Auditing {spec.name} ({spec.version})")
if vulns_to_ignore:
filtered_vulns = [v for v in vulns if not v.has_any_id(vulns_to_ignore)]
vuln_ignore_count += len(vulns) - len(filtered_vulns)
vulns = filtered_vulns
result[spec] = vulns
if len(vulns) > 0:
pkg_count += 1
Expand Down Expand Up @@ -442,7 +456,8 @@ def audit() -> None:
if vuln_count > 0:
summary_msg = (
f"Found {vuln_count} known "
f"{'vulnerability' if vuln_count == 1 else 'vulnerabilities'} "
f"{'vulnerability' if vuln_count == 1 else 'vulnerabilities'}"
f"{(vuln_ignore_count and ', ignored %d ' % vuln_ignore_count) or ' '}"
f"in {pkg_count} {'package' if pkg_count == 1 else 'packages'}"
)
if args.fix:
Expand All @@ -457,7 +472,14 @@ def audit() -> None:
if pkg_count != fixed_pkg_count:
sys.exit(1)
else:
print("No known vulnerabilities found", file=sys.stderr)
summary_msg = "No known vulnerabilities found"
if vuln_ignore_count:
summary_msg += f", {vuln_ignore_count} ignored"

print(
summary_msg,
file=sys.stderr,
)
# If our output format is a "manifest" format we always emit it,
# even if nothing other than a dependency summary is present.
if skip_count > 0 or formatter.is_manifest:
Expand Down
9 changes: 8 additions & 1 deletion test/test_cli.py
Expand Up @@ -10,9 +10,12 @@
([], 1, 1, "Found 1 known vulnerability in 1 package"),
([], 2, 1, "Found 2 known vulnerabilities in 1 package"),
([], 2, 2, "Found 2 known vulnerabilities in 2 packages"),
(["--ignore-vuln", "bar"], 2, 2, "Found 2 known vulnerabilities, ignored 1 in 2 packages"),
(["--fix"], 1, 1, "fixed 1 vulnerability in 1 package"),
(["--fix"], 2, 1, "fixed 2 vulnerabilities in 1 package"),
(["--fix"], 2, 2, "fixed 2 vulnerabilities in 2 packages"),
([], 0, 0, "No known vulnerabilities found"),
(["--ignore-vuln", "bar"], 0, 1, "No known vulnerabilities found, 1 ignored"),
],
)
def test_plurals(capsys, monkeypatch, args, vuln_count, pkg_count, expected):
Expand All @@ -30,11 +33,15 @@ def test_plurals(capsys, monkeypatch, args, vuln_count, pkg_count, expected):
canonical_name="something" + str(i),
version=1,
),
[pretend.stub(fix_versions=[2], id="foo")] * (vuln_count // pkg_count),
[pretend.stub(fix_versions=[2], id="foo", aliases=set(), has_any_id=lambda x: False)]
* (vuln_count // pkg_count),
)
for i in range(pkg_count)
]

if "--ignore-vuln" in args:
result[0][1].append(pretend.stub(id="bar", aliases=set(), has_any_id=lambda x: True))

auditor = pretend.stub(audit=lambda a: result)
monkeypatch.setattr(pip_audit._cli, "Auditor", lambda *a, **kw: auditor)

Expand Down

0 comments on commit 27c2574

Please sign in to comment.