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
rhel: add csaf/vex updater #1165
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1165 +/- ##
========================================
Coverage 56.24% 56.25%
========================================
Files 266 270 +4
Lines 16838 17336 +498
========================================
+ Hits 9471 9752 +281
- Misses 6402 6558 +156
- Partials 965 1026 +61 ☔ View full report in Codecov by Sentry. |
a834c67
to
0c787f2
Compare
758d6a4
to
fbfbf82
Compare
89006e1
to
4deb036
Compare
12e41cb
to
052599d
Compare
e30a749
to
abfa0e0
Compare
I figure this is probably ready for a review even if it can't be fully merged yet |
@@ -63,6 +64,7 @@ func inner(ctx context.Context) error { | |||
updater.Register("debian", df) | |||
|
|||
updater.Register("osv", new(osv.Factory)) | |||
updater.Register("rhel-vex", new(vex.Factory)) |
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.
Is the idea to support both OVAL and VEX at the same time for a period, or will this PR remove "rhel"
, too, later?
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.
Probably remove the OVAL in the same PR
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.
@RTann check out the last commit
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.
just curious about the ordering here. is it pretty arbitrary?
bf52b0b
to
ab36dfd
Compare
0896bbd
to
818d85d
Compare
Replace the Red Hat OVALv2 update source with the Red Hat CSAF/VEX data. Signed-off-by: crozzy <joseph.crosland@gmail.com>
Start matching repository CPEs based on the CPE subset relation. This change interprets VEX CPEs identifying Red Hat repositories as CPE matching expressions and looks for a subset relation with the record's repositoty CPE. Signed-off-by: crozzy <joseph.crosland@gmail.com>
Previously the IgnoreUnpatched config key was a part of the RHEL updater and would dictate whether or not the updater would ingest unpatched vulnerabilities. This change moves that key to the RHEL matcher and dictates whether the matcher should check for a fixed_in_version when querying potential vulnerabilities. This makes the config option more usable at the expense of DB size. Signed-off-by: crozzy <joseph.crosland@gmail.com>
Given that the rhel-vex data will be responsible for Red Hat vulnerabilities we no longer want the existing OVAL updater to be a default (or even selectable). This patch also removes existing RHEL OVAL data from the matcher DB. Signed-off-by: crozzy <joseph.crosland@gmail.com>
-- The rhel-vex updater will now be responsible for RHEL advisories so we have | ||
-- to delete the existing rhel vulnerabilities. | ||
DELETE FROM update_operation WHERE updater ~ 'RHEL[5-9]-*'; | ||
DELETE FROM vuln v2 where v2.updater ~ 'RHEL[5-9]-*'; |
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.
just curious why call this v2
?
@@ -70,6 +70,8 @@ func buildGetQuery(record *claircore.IndexRecord, opts *datastore.GetOpts) (stri | |||
ex = goqu.Ex{"dist_arch": record.Distribution.Arch} | |||
case driver.RepositoryName: | |||
ex = goqu.Ex{"repo_name": record.Repository.Name} | |||
case driver.HasFixedInVersion: | |||
ex = goqu.Ex{"fixed_in_version": goqu.Op{"neq": ""}} |
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.
just curious if this is preferred over something like exp.NeqOp.String()
. This is wordier, but protects against mistakes and future-proofs it (though I doubt it'll change, and it looks correct go me)
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 guess the unit test also proves this works and can future-proof it
@@ -142,7 +142,7 @@ func (mc *Controller) filter(ctx context.Context, interested []*claircore.IndexR | |||
if err != nil { | |||
return nil, err | |||
} | |||
filtered[record.Package.ID] = match | |||
filtered[record.Package.ID] = append(filtered[record.Package.ID], match...) |
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.
hard to tell without context: what was this overwriting before? How bad was this?
driver.PackageModule, | ||
driver.RepositoryName, | ||
func (m *Matcher) Query() []driver.MatchConstraint { | ||
mcs := []driver.MatchConstraint{driver.PackageModule} |
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.
curious why do we check the package module? does every package have a related module? why not check for distribution name?
// Vulnerable() will interpret the claircore.Vulnerability.Repo.CPE | ||
// as a CPE match expression and in order to be considered vulnerable | ||
// the relationship between claircore.IndexRecord.Repository.CPE and | ||
// the claircore.Vulnerability.Repo.CPE needs to be a CPE Name Comparison | ||
// Relation of SUBSET(⊂)(source is a subset of, or equal to the target). | ||
// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf Section 6.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.
// Vulnerable() will interpret the claircore.Vulnerability.Repo.CPE | |
// as a CPE match expression and in order to be considered vulnerable | |
// the relationship between claircore.IndexRecord.Repository.CPE and | |
// the claircore.Vulnerability.Repo.CPE needs to be a CPE Name Comparison | |
// Relation of SUBSET(⊂)(source is a subset of, or equal to the target). | |
// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf Section 6.2. | |
// Vulnerable will interpret the claircore.Vulnerability.Repo.CPE | |
// as a CPE match expression, and to be considered vulnerable, | |
// the relationship between claircore.IndexRecord.Repository.CPE and | |
// the claircore.Vulnerability.Repo.CPE needs to be a CPE Name Comparison | |
// Relation of SUBSET(⊂)(source is a subset of, or equal to the target). | |
// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7696.pdf Section 6.2. |
if err != nil { | ||
return nil, hint, fmt.Errorf("error making advisory request %w", err) | ||
} | ||
if res.StatusCode != http.StatusOK { |
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.
missing a Body.Close()
when we reach this
buf.Reset() | ||
bc.Reset() | ||
l++ | ||
res.Body.Close() |
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.
another option is to put this into a separate func so we can defer
without worrying about the loop
return nil, hint, fmt.Errorf("unexpected response from advisary URL: %s %s", res.Status, req.URL) | ||
} | ||
|
||
_, err = buf.ReadFrom(res.Body) |
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.
so does this cover the case where this is the first time we read the VEX data and there is a newer version of a few files? This will overwrite data for those files?
) | ||
|
||
// Parse implements [driver.Updater]. | ||
func (u *VEXUpdater) Parse(ctx context.Context, contents io.ReadCloser) ([]*claircore.Vulnerability, error) { |
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.
For StackRox's usage of Claircore at the moment, we pretty much start fresh every time. Does not implementing Parse
mean our use case may not work? Related: will the jsonblob stuff work OOTB?
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.
Will need to look at this another time
TODO