New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an 'audit' goal which checks lockfiles against reported vulnerabilities. #20838
base: main
Are you sure you want to change the base?
Conversation
Thanks for the links! Interesting to see someone elses build of this tool. The pip-audit tool is itself a wrapper around the pypi/osv vulnerability api's, but it also does a bunch of extra work we don't need or want - eg: it performs a full resolve and potentially downloads more packages. It also goes poking through your local pip cache which doesn't play well with being sandboxed. Because I wrote this tool to operate only over lockfiles we know we can skip all of that extra work. It works out smaller, lighter weight, and doesn't require a bunch of new 3rdparty deps. I've tried to write it in such a way that we can add an osv backend to it if people prefer that over pypi. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice stuff!
I think we may want to split the implementation into the core audit goal feature, and then have the Python part with pip_audit in the python backend. cf. how the publish
goal is partitioned.
(some inconsistencies in naming as well, pip audit vs. pypi audit..)
request_type.field_set_type.create(target) # type: ignore[misc] | ||
for target in targets | ||
if ( | ||
request_type.tool_id in specified_ids |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tool filter ought to be applied outside of the request_type constructor, to avoid creating empty AuditRequest
s.`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this is in a comprehension - if the if
on line 102 doesn't pass, line 100 will not execute.
Edited to add: I double checked this with:
a = [1,2,3,4]
def foo(x):
raise Exception(x)
evens = tuple(foo(x) for x in a if x%2 == 0)
This results in Exception: 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the if on line 102 doesn't pass, line 100 will not execute.
Yes, that is clear. But if the request types tool id is not in the specified_ids, we will not create any field sets, resulting in an empty AuditRequest. Moving the check outside the constructor will eliminate these no-op requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. Good catch!
specified_ids = determine_specified_tool_ids( | ||
"audit", | ||
[ | ||
"pypi-audit", | ||
], | ||
request_types, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming this is temporary hack until a proper option is added...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, at present the only audit available is running against the pypi vulnerability database. In future we might want to use osv, or add ways to audit 3rdparty deps for languages other than python.
Just to make sure I've got this straight:
Do I leave anything in The naming is a bit of a mess. If anyone's got preferences I'm all ears. pip-audit is a thing people are already familiar with as a tool. pypi-audit is slightly more accurate in that we're actually hitting the pypi api. |
Ah, right, slightly misleading phrasing on my part. This doesn't have to be a core builtin goal, but stay in a backend (where it is), being the "core" (or perhaps rather, the "common" parts of the audit feature) in the
Yes, and perhaps register these python specific audit rules from
Keep audit related
I think |
(Narrowly on the naming, if we are not using `pip-audit the program we should not call it "pip-audit". pypi-audit is reasonable.) |
|
||
|
||
class AuditSubsystem(GoalSubsystem): | ||
name = "audit" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be experimental-audit
for now like we did for deploy
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We certainly could. I guess we could look at how big risk for change is there?
Deploy feels like it could be more sensitive to how it works, compared to presenting a list of applicable security reports, which could warrant this to go straight to a "stable" goal name.. for me it's fine either way, but I'm 👍🏽 for having the discussion to settle it.
@@ -240,3 +241,6 @@ args = ["-Yrangepos", "-Xlint:unused"] | |||
|
|||
[scala-infer] | |||
force_add_siblings_as_dependencies = false | |||
|
|||
[pypi-audit] | |||
lockfile_vulnerability_excludes = { "python-default" = ["GHSA-w596-4wvx-j9j6"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Could you add a comment for why this can be ignored? It's not just an example, correct?
- This is just me being unfamiliar with the space, but how do we end up with a GitHub advisory ID instead of a CVE or python specific one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. I think every exception should be made with a note as to why it's being excluded. Perhaps this should be generally encouraged, so we could have a syntax like:
lockfile_vulnerability_excludes = { "python-default" = ["GHSA-w596-4wvx-j9j6"] } | |
lockfile_vulnerability_excludes = { "python-default" = [{"id": "GHSA-w596-4wvx-j9j6", "note": "This is N/A for reasons a, b and c."}] } |
and potentially warn/err if there is no note
.
These excludes could then be briefly mentioned, along with the note, when running pants audit
for visibility.
Co-authored-by: Andreas Stenius <git@astekk.se>
Thanks for the contribution. When you have a chance (and this is close to ready), please merge |
This fetches vulnerability data from the pypi json api and prints a vulnerability report for each lockfile in the repo.
Current results from the Pants repo:
I've added a way to exclude specific vulnerabilities from the report, as sometimes they're not relevant. eg: GHSA-w596-4wvx-j9j6 only affects subversion projects.