Add software sanitation on ingest back, use it to fix DCV Viewer versions (#31251)
We'll want to pull this into a feed so fixes don't take a Fleet release to propagate, and some fixes currently in the vulns mutations list should probably move over here (as they're also dealing with non-semver versions), but that's out of scope for this particular fix. Fixes #31123. # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] Added/updated automated tests - [x] Manual QA for all new/changed functionality
This commit is contained in:
@@ -0,0 +1 @@
|
||||
* Added back software mutation on ingestion to fix non-semver-compliant software versions, starting with DCV Viewer.
|
||||
@@ -1756,6 +1756,8 @@ func directIngestSoftware(ctx context.Context, logger log.Logger, host *fleet.Ho
|
||||
continue
|
||||
}
|
||||
|
||||
MutateSoftwareOnIngestion(s, logger)
|
||||
|
||||
if shouldRemoveSoftware(host, s) {
|
||||
continue
|
||||
}
|
||||
@@ -1799,6 +1801,42 @@ func directIngestSoftware(ctx context.Context, logger log.Logger, host *fleet.Ho
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
dcvVersionFormat = regexp.MustCompile(`^(\d+\.\d+)\s*\(r(\d+)\)$`)
|
||||
softwareSanitizers = []struct {
|
||||
matches func(*fleet.Software) bool
|
||||
mutate func(*fleet.Software, log.Logger)
|
||||
}{
|
||||
{
|
||||
matches: func(s *fleet.Software) bool {
|
||||
return s.Source == "apps" && s.BundleIdentifier == "com.nicesoftware.dcvviewer"
|
||||
},
|
||||
mutate: func(s *fleet.Software, logger log.Logger) {
|
||||
if versionMatches := dcvVersionFormat.FindStringSubmatch(s.Version); len(versionMatches) == 3 {
|
||||
s.Version = fmt.Sprintf("%s.%s", versionMatches[1], versionMatches[2])
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// MutateSoftwareOnIngestion performs any tweaks required to the ingested software fields.
|
||||
//
|
||||
// Some fields are reported with known incorrect values and we need to fix them before using them.
|
||||
func MutateSoftwareOnIngestion(s *fleet.Software, logger log.Logger) {
|
||||
for _, softwareSanitizer := range softwareSanitizers {
|
||||
if softwareSanitizer.matches(s) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
level.Warn(logger).Log("msg", "panic during software mutation", "softwareName", s.Name, "softwareVersion", s.Version, "error", r)
|
||||
}
|
||||
}()
|
||||
softwareSanitizer.mutate(s, logger)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shouldRemoveSoftware returns whether or not we should remove the given Software item from this
|
||||
// host's software list.
|
||||
func shouldRemoveSoftware(h *fleet.Host, s *fleet.Software) bool {
|
||||
|
||||
@@ -33,6 +33,35 @@ import (
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
func TestSoftwareIngestionMutations(t *testing.T) {
|
||||
dcvViewer := &fleet.Software{
|
||||
BundleIdentifier: "com.nicesoftware.dcvviewer",
|
||||
Source: "apps",
|
||||
Version: "2024.0 (r8004)",
|
||||
}
|
||||
|
||||
MutateSoftwareOnIngestion(dcvViewer, log.NewNopLogger())
|
||||
assert.Equal(t, "2024.0.8004", dcvViewer.Version)
|
||||
|
||||
noOp := &fleet.Software{
|
||||
BundleIdentifier: "com.nicesoftware.dcvviewer",
|
||||
Source: "apps",
|
||||
Version: "2024",
|
||||
}
|
||||
|
||||
MutateSoftwareOnIngestion(dcvViewer, log.NewNopLogger())
|
||||
assert.Equal(t, "2024", noOp.Version)
|
||||
|
||||
noMatch := &fleet.Software{
|
||||
BundleIdentifier: "com.google.chrome",
|
||||
Source: "apps",
|
||||
Version: "2024.0 (r8004)",
|
||||
}
|
||||
|
||||
MutateSoftwareOnIngestion(noMatch, log.NewNopLogger())
|
||||
assert.Equal(t, "2024.0 (r8004)", noMatch.Version)
|
||||
}
|
||||
|
||||
func TestDetailQueryNetworkInterfaces(t *testing.T) {
|
||||
var initialHost fleet.Host
|
||||
host := initialHost
|
||||
|
||||
Reference in New Issue
Block a user