mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Vulnerability processing should ignore software without version (#14612)
#13615 - [X] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or docs/Contributing/API-for-contributors.md)~ - ~[ ] Documented any permissions changes (docs/Using Fleet/manage-access.md)~ - ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements)~ - ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for new osquery data ingestion features.~ - [X] Added/updated tests - [X] Manual QA for all new/changed functionality - ~For Orbit and Fleet Desktop changes:~ - ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows and Linux.~ - ~[ ] Auto-update manual QA, from released version of component to new version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
This commit is contained in:
parent
3869b41041
commit
2fd6fa4e04
1
changes/13615-ignore-software-without-version
Normal file
1
changes/13615-ignore-software-without-version
Normal file
@ -0,0 +1 @@
|
||||
* Updated vulnerability processing to ignore software that has been ingested without a version.
|
@ -301,6 +301,8 @@ With a somewhat normalized list of software, in order to search CVEs for it, we
|
||||
|
||||
As described briefly above, we do this by translating the NVD database of CPEs into a [sqlite database that helps Fleet do the lookup of CPEs very quickly](https://github.com/fleetdm/nvd).
|
||||
|
||||
NOTE: Software that was ingested with an empty `version` field will be ignored by the NVD vulnerability processing.
|
||||
|
||||
#### How accurate is this translation process?
|
||||
|
||||
This is the most error prone part of the process.
|
||||
|
@ -397,12 +397,33 @@ func TranslateSoftwareToCPE(
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "getting value from iterator")
|
||||
}
|
||||
cpe, err := CPEFromSoftware(db, software, cpeTranslations, reCache)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("software->cpe", "error translating to CPE, skipping...", "err", err)
|
||||
continue
|
||||
var cpe string
|
||||
// Skip software without version to avoid false positives in the CPE
|
||||
// matching process.
|
||||
if software.Version == "" {
|
||||
level.Debug(logger).Log(
|
||||
"msg", "skipping software without version",
|
||||
"software", software.Name,
|
||||
"source", software.Source,
|
||||
)
|
||||
// We want to continue here in case the software had an invalid CPE
|
||||
// generated by a previous version of Fleet.
|
||||
} else {
|
||||
cpe, err = CPEFromSoftware(db, software, cpeTranslations, reCache)
|
||||
if err != nil {
|
||||
level.Error(logger).Log(
|
||||
"msg", "error translating to CPE, skipping",
|
||||
"software", software.Name,
|
||||
"version", software.Version,
|
||||
"source", software.Source,
|
||||
"err", err,
|
||||
)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if cpe == software.GenerateCPE {
|
||||
// If the generated CPE hasn't changed from what's already stored in the DB
|
||||
// then we don't need to do anything.
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -297,8 +297,6 @@ func TestConsumeCPEBuffer(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTranslateSoftwareToCPE(t *testing.T) {
|
||||
nettest.Run(t)
|
||||
|
||||
tempDir := t.TempDir()
|
||||
|
||||
ds := new(mock.Store)
|
||||
@ -361,6 +359,52 @@ func TestTranslateSoftwareToCPE(t *testing.T) {
|
||||
assert.True(t, iterator.closed)
|
||||
}
|
||||
|
||||
// TestTranslateSoftwareToCPEIgnoreEmptyVersion tests that TranslateSoftwareToCPE ignores
|
||||
// software that was ingested with an empty version field. The test will simulate a previous
|
||||
// version of Fleet storing an incorrect CPE for the software, to test that an upgrade
|
||||
// will clear out the invalid CPE from the DB.
|
||||
func TestTranslateSoftwareToCPEIgnoreEmptyVersion(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
ds := new(mock.Store)
|
||||
|
||||
// The incorrect CPE for the software should now be deleted because the ingested software doesn't
|
||||
// have a version field.
|
||||
ds.DeleteSoftwareCPEsFunc = func(ctx context.Context, cpes []fleet.SoftwareCPE) (int64, error) {
|
||||
require.Len(t, cpes, 1)
|
||||
require.Equal(t, cpes[0].SoftwareID, uint(1))
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
ds.AllSoftwareIteratorFunc = func(ctx context.Context, q fleet.SoftwareIterQueryOptions) (fleet.SoftwareIterator, error) {
|
||||
return &fakeSoftwareIterator{
|
||||
softwares: []*fleet.Software{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "foobar",
|
||||
Version: "",
|
||||
BundleIdentifier: "vendor2",
|
||||
Source: "apps",
|
||||
// Set an incorrect CPE on the DB to simulate a CPE being generated incorrectly
|
||||
// for this software on a previous version of Fleet.
|
||||
GenerateCPE: "cpe:2.3:a:vendor2:foobar:*:*:*:*:*:macos:*:*",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
items, err := cpedict.Decode(strings.NewReader(XmlCPETestDict))
|
||||
require.NoError(t, err)
|
||||
|
||||
dbPath := filepath.Join(tempDir, "cpe.sqlite")
|
||||
err = GenerateCPEDB(dbPath, items)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = TranslateSoftwareToCPE(context.Background(), ds, tempDir, kitlog.NewNopLogger())
|
||||
require.NoError(t, err)
|
||||
require.True(t, ds.DeleteSoftwareCPEsFuncInvoked)
|
||||
}
|
||||
|
||||
func TestSyncsCPEFromURL(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
zw := gzip.NewWriter(w)
|
||||
|
Loading…
Reference in New Issue
Block a user