Skip to content

Commit 113c53a

Browse files
committed
feat: allow to remove fields from vulnerability reports
1 parent 1caa4d4 commit 113c53a

File tree

7 files changed

+181
-43
lines changed

7 files changed

+181
-43
lines changed

deploy/helm/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Keeps security report resources updated
129129
| targetNamespaces | string | `""` | targetNamespace defines where you want trivy-operator to operate. By default, it's a blank string to select all namespaces, but you can specify another namespace, or a comma separated list of namespaces. |
130130
| targetWorkloads | string | `"pod,replicaset,replicationcontroller,statefulset,daemonset,cronjob,job"` | targetWorkloads is a comma seperated list of Kubernetes workload resources to be included in the vulnerability and config-audit scans if left blank, all workload resources will be scanned |
131131
| tolerations | list | `[]` | tolerations set the operator tolerations |
132-
| trivy.additionalVulnerabilityReportFields | string | `""` | additionalVulnerabilityReportFields is a comma separated list of additional fields which can be added to the VulnerabilityReport. Supported parameters: Description, Links, CVSS, Target, Class, PackagePath and PackageType |
132+
| trivy.additionalVulnerabilityReportFields | string | `""` | additionalVulnerabilityReportFields is a comma separated list of additional fields which can be added to the VulnerabilityReport. Supported parameters: Description, Links, CVSS, Target, Class, PackagePath and PackageType. Fields can also be removed with a leading minus sign `-`. Supported parameters: -Resource, -InstalledVersion, -FixedVersion, -PublishedDate, -LastModifiedDate, -Severity, -Title, -PrimaryLink, -Score and -PURL. |
133133
| trivy.clientServerSkipUpdate | bool | `false` | clientServerSkipUpdate is the flag to enable skip databases update for Trivy client. Only applicable in ClientServer mode. |
134134
| trivy.command | string | `"image"` | command. One of `image`, `filesystem` or `rootfs` scanning, depending on the target type required for the scan. For 'filesystem' and `rootfs` scanning, ensure that the `trivyOperator.scanJobPodTemplateContainerSecurityContext` is configured to run as the root user (runAsUser = 0). |
135135
| trivy.configFile | string | `nil` | configFile can be used to tell Trivy to use specific options available only in the config file (e.g. Mirror registries). |

deploy/helm/values.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ trivy:
398398
priorityClassName: ""
399399

400400
# -- additionalVulnerabilityReportFields is a comma separated list of additional fields which
401-
# can be added to the VulnerabilityReport. Supported parameters: Description, Links, CVSS, Target, Class, PackagePath and PackageType
401+
# can be added to the VulnerabilityReport. Supported parameters: Description, Links, CVSS, Target, Class, PackagePath and PackageType.
402+
# Fields can also be removed with a leading minus sign `-`. Supported parameters: -Resource, -InstalledVersion, -FixedVersion, -PublishedDate, -LastModifiedDate, -Severity, -Title, -PrimaryLink, -Score and -PURL.
402403
additionalVulnerabilityReportFields: ""
403404

404405
# -- httpProxy is the HTTP proxy used by Trivy to download the vulnerabilities database from GitHub.

docs/docs/vulnerability-scanning/trivy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ EOF
101101
| `trivy.javaDbRepository` | `mirror.gcr.io/aquasec/trivy-java-db` | External OCI Registry to download the vulnerability database for Java |
102102
| `trivy.dbRepositoryInsecure` | `false` | The Flag to enable insecure connection for downloading trivy-db via proxy (air-gaped env) |
103103
| `trivy.mode` | `Standalone` | Trivy client mode. Either `Standalone` or `ClientServer`. Depending on the active mode other settings might be applicable or required. |
104-
| `additionalVulnerabilityReportFields` | N/A | A comma separated list of additional fields which can be added to the VulnerabilityReport. Possible values: `Description,Links,CVSS,Target,Class,PackagePath,PackageType`. Description will add more data about vulnerability. Links - all the references to a specific vulnerability. CVSS - data about CVSSv2/CVSSv3 scoring and vectors. Target - vulnerable element. Class - OS or library vulnerability |
104+
| `additionalVulnerabilityReportFields` | N/A | A comma separated list of additional fields which can be added to the VulnerabilityReport. Possible values: `Description,Links,CVSS,Target,Class,PackagePath,PackageType`. Description will add more data about vulnerability. Links - all the references to a specific vulnerability. CVSS - data about CVSSv2/CVSSv3 scoring and vectors. Target - vulnerable element. Class - OS or library vulnerability. Fields can also be removed with a leading minus sign `-`. Possible values: `Resource,InstalledVersion,FixedVersion,PublishedDate,LastModifiedDate,Severity,Title,PrimaryLink,Score,PURL` |
105105
| `trivy.command` | `image` | command. One of `image`, `filesystem` or `rootfs` scanning. Depending on the target type required for the scan. |
106106
| `trivy.slow` | `true` | This flag is to use less CPU/memory for scanning though it takes more time than normal scanning. It fits small-footprint |
107107
| `trivy.severity` | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | A comma separated list of severity levels reported by Trivy |

pkg/plugins/trivy/config.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,50 @@ type Config struct {
8080
}
8181

8282
func (c Config) GetAdditionalVulnerabilityReportFields() vulnerabilityreport.AdditionalFields {
83-
addFields := vulnerabilityreport.AdditionalFields{}
83+
addFields := vulnerabilityreport.NewDefaultAdditionalFields()
8484

8585
fields, ok := c.Data[keyTrivyAdditionalVulnerabilityReportFields]
8686
if !ok {
8787
return addFields
8888
}
8989
for _, field := range strings.Split(fields, ",") {
90+
value := !strings.HasPrefix(field, "-")
91+
field = strings.TrimPrefix(field, "-")
9092
switch strings.TrimSpace(field) {
93+
case "Resource":
94+
addFields.Resource = value
95+
case "InstalledVersion":
96+
addFields.InstalledVersion = value
97+
case "FixedVersion":
98+
addFields.FixedVersion = value
99+
case "PublishedDate":
100+
addFields.PublishedDate = value
101+
case "LastModifiedDate":
102+
addFields.LastModifiedDate = value
103+
case "Severity":
104+
addFields.Severity = value
105+
case "Title":
106+
addFields.Title = value
107+
case "PrimaryLink":
108+
addFields.PrimaryLink = value
109+
case "Score":
110+
addFields.Score = value
111+
case "PURL":
112+
addFields.PURL = value
91113
case "Description":
92-
addFields.Description = true
114+
addFields.Description = value
93115
case "Links":
94-
addFields.Links = true
116+
addFields.Links = value
95117
case "CVSS":
96-
addFields.CVSS = true
118+
addFields.CVSS = value
97119
case "Target":
98-
addFields.Target = true
120+
addFields.Target = value
99121
case "Class":
100-
addFields.Class = true
122+
addFields.Class = value
101123
case "PackageType":
102-
addFields.PackageType = true
124+
addFields.PackageType = value
103125
case "PackagePath":
104-
addFields.PkgPath = true
126+
addFields.PkgPath = value
105127
}
106128
}
107129
return addFields

pkg/plugins/trivy/config_test.go

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
8888
{
8989
name: "no additional fields are set",
9090
configData: Config{PluginConfig: trivyoperator.PluginConfig{}},
91-
additionalFields: vulnerabilityreport.AdditionalFields{},
91+
additionalFields: vulnerabilityreport.NewDefaultAdditionalFields(),
9292
},
9393
{
9494
name: "all additional fields are set",
@@ -97,7 +97,26 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
9797
"trivy.additionalVulnerabilityReportFields": "PackageType,PkgPath,Class,Target,Links,Description,CVSS",
9898
},
9999
}},
100-
additionalFields: vulnerabilityreport.AdditionalFields{Description: true, Links: true, CVSS: true, Class: true, PackageType: true, PkgPath: true, Target: true},
100+
additionalFields: vulnerabilityreport.AdditionalFields{
101+
// default
102+
Resource: true,
103+
InstalledVersion: true,
104+
FixedVersion: true,
105+
PublishedDate: true,
106+
LastModifiedDate: true,
107+
Severity: true,
108+
Title: true,
109+
PrimaryLink: true,
110+
Score: true,
111+
PURL: true,
112+
// added
113+
Description: true,
114+
Links: true,
115+
CVSS: true,
116+
Class: true,
117+
PackageType: true,
118+
Target: true,
119+
},
101120
},
102121
{
103122
name: "some additional fields are set",
@@ -106,19 +125,80 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
106125
"trivy.additionalVulnerabilityReportFields": "PackageType,Target,Links,CVSS",
107126
},
108127
}},
109-
additionalFields: vulnerabilityreport.AdditionalFields{Links: true, CVSS: true, PackageType: true, Target: true},
128+
additionalFields: vulnerabilityreport.AdditionalFields{
129+
// default
130+
Resource: true,
131+
InstalledVersion: true,
132+
FixedVersion: true,
133+
PublishedDate: true,
134+
LastModifiedDate: true,
135+
Severity: true,
136+
Title: true,
137+
PrimaryLink: true,
138+
Score: true,
139+
PURL: true,
140+
// added
141+
Links: true,
142+
CVSS: true,
143+
PackageType: true,
144+
Target: true,
145+
},
146+
},
147+
{
148+
name: "all fields are removed",
149+
configData: Config{PluginConfig: trivyoperator.PluginConfig{
150+
Data: map[string]string{
151+
"trivy.additionalVulnerabilityReportFields": "-Resource,-InstalledVersion,-FixedVersion,-PublishedDate,-LastModifiedDate,-Severity,-Title,-PrimaryLink,-Score,-PURL",
152+
},
153+
}},
154+
additionalFields: vulnerabilityreport.AdditionalFields{},
155+
},
156+
{
157+
name: "some fields are added and some are removed",
158+
configData: Config{PluginConfig: trivyoperator.PluginConfig{
159+
Data: map[string]string{
160+
"trivy.additionalVulnerabilityReportFields": "CVSS,PackageType,-PublishedDate,-LastModifiedDate",
161+
},
162+
}},
163+
additionalFields: vulnerabilityreport.AdditionalFields{
164+
// default
165+
Resource: true,
166+
InstalledVersion: true,
167+
FixedVersion: true,
168+
PublishedDate: false, // removed
169+
LastModifiedDate: false, // removed
170+
Severity: true,
171+
Title: true,
172+
PrimaryLink: true,
173+
Score: true,
174+
PURL: true,
175+
// added
176+
CVSS: true,
177+
PackageType: true,
178+
},
110179
},
111180
}
112181

113182
for _, tc := range testCases {
114183
t.Run(tc.name, func(t *testing.T) {
115184
addFields := tc.configData.GetAdditionalVulnerabilityReportFields()
185+
assert.Equal(t, tc.additionalFields.Resource, addFields.Resource)
186+
assert.Equal(t, tc.additionalFields.InstalledVersion, addFields.InstalledVersion)
187+
assert.Equal(t, tc.additionalFields.FixedVersion, addFields.FixedVersion)
188+
assert.Equal(t, tc.additionalFields.PublishedDate, addFields.PublishedDate)
189+
assert.Equal(t, tc.additionalFields.LastModifiedDate, addFields.LastModifiedDate)
190+
assert.Equal(t, tc.additionalFields.Severity, addFields.Severity)
191+
assert.Equal(t, tc.additionalFields.Title, addFields.Title)
192+
assert.Equal(t, tc.additionalFields.PrimaryLink, addFields.PrimaryLink)
193+
assert.Equal(t, tc.additionalFields.Score, addFields.Score)
194+
assert.Equal(t, tc.additionalFields.PURL, addFields.PURL)
116195
assert.Equal(t, tc.additionalFields.Description, addFields.Description)
196+
assert.Equal(t, tc.additionalFields.Links, addFields.Links)
117197
assert.Equal(t, tc.additionalFields.CVSS, addFields.CVSS)
118198
assert.Equal(t, tc.additionalFields.Target, addFields.Target)
119-
assert.Equal(t, tc.additionalFields.PackageType, addFields.PackageType)
120199
assert.Equal(t, tc.additionalFields.Class, addFields.Class)
121-
assert.Equal(t, tc.additionalFields.Links, addFields.Links)
200+
assert.Equal(t, tc.additionalFields.PackageType, addFields.PackageType)
201+
assert.Equal(t, tc.additionalFields.PkgPath, addFields.PkgPath)
122202
})
123203
}
124204
}

pkg/plugins/trivy/plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ func (p *plugin) ParseReportData(ctx trivyoperator.PluginContext, imageRef strin
182182
}
183183
vulnerabilities := make([]v1alpha1.Vulnerability, 0)
184184
secrets := make([]v1alpha1.ExposedSecret, 0)
185+
addFields := config.GetAdditionalVulnerabilityReportFields()
185186
for _, report := range reports.Results {
186-
addFields := config.GetAdditionalVulnerabilityReportFields()
187187
vulnerabilities = append(vulnerabilities, vulnerabilityreport.GetVulnerabilitiesFromScanResult(report, addFields)...)
188188
secrets = append(secrets, getExposedSecretsFromScanResult(report)...)
189189
}

pkg/vulnerabilityreport/io.go

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -129,41 +129,76 @@ func (r *readWriter) FindByOwner(ctx context.Context, owner kube.ObjectRef) ([]v
129129
}
130130

131131
type AdditionalFields struct {
132-
Description bool
133-
Links bool
134-
CVSS bool
135-
Target bool
136-
Class bool
137-
PackageType bool
138-
PkgPath bool
132+
Resource bool
133+
InstalledVersion bool
134+
FixedVersion bool
135+
PublishedDate bool
136+
LastModifiedDate bool
137+
Severity bool
138+
Title bool
139+
PrimaryLink bool
140+
Score bool
141+
PURL bool
142+
Description bool
143+
Links bool
144+
CVSS bool
145+
Target bool
146+
Class bool
147+
PackageType bool
148+
PkgPath bool
149+
}
150+
151+
func NewDefaultAdditionalFields() AdditionalFields {
152+
return AdditionalFields{
153+
Resource: true,
154+
InstalledVersion: true,
155+
FixedVersion: true,
156+
PublishedDate: true,
157+
LastModifiedDate: true,
158+
Severity: true,
159+
Title: true,
160+
PrimaryLink: true,
161+
Score: true,
162+
PURL: true,
163+
}
139164
}
140165

141166
func GetVulnerabilitiesFromScanResult(report ty.Result, addFields AdditionalFields) []v1alpha1.Vulnerability {
142167
vulnerabilities := make([]v1alpha1.Vulnerability, 0)
143168

144169
for _, sr := range report.Vulnerabilities {
145-
var pd, lmd string
146-
if sr.PublishedDate != nil {
147-
pd = sr.PublishedDate.Format(time.RFC3339)
148-
}
149-
if sr.LastModifiedDate != nil {
150-
lmd = sr.LastModifiedDate.Format(time.RFC3339)
151-
}
152170
vulnerability := v1alpha1.Vulnerability{
153-
VulnerabilityID: sr.VulnerabilityID,
154-
Resource: sr.PkgName,
155-
InstalledVersion: sr.InstalledVersion,
156-
FixedVersion: sr.FixedVersion,
157-
PublishedDate: pd,
158-
LastModifiedDate: lmd,
159-
Severity: v1alpha1.Severity(sr.Severity),
160-
Title: sr.Title,
161-
PrimaryLink: sr.PrimaryURL,
162-
Links: []string{},
163-
Score: GetScoreFromCVSS(GetCvssV3(sr.CVSS)),
171+
VulnerabilityID: sr.VulnerabilityID,
164172
}
165173

166-
if sr.PkgIdentifier.PURL != nil {
174+
if addFields.Resource {
175+
vulnerability.Resource = sr.PkgName
176+
}
177+
if addFields.InstalledVersion {
178+
vulnerability.InstalledVersion = sr.InstalledVersion
179+
}
180+
if addFields.FixedVersion {
181+
vulnerability.FixedVersion = sr.FixedVersion
182+
}
183+
if addFields.PublishedDate && sr.PublishedDate != nil {
184+
vulnerability.PublishedDate = sr.PublishedDate.Format(time.RFC3339)
185+
}
186+
if addFields.LastModifiedDate && sr.LastModifiedDate != nil {
187+
vulnerability.LastModifiedDate = sr.LastModifiedDate.Format(time.RFC3339)
188+
}
189+
if addFields.Severity {
190+
vulnerability.Severity = v1alpha1.Severity(sr.Severity)
191+
}
192+
if addFields.Title {
193+
vulnerability.Title = sr.Title
194+
}
195+
if addFields.PrimaryLink {
196+
vulnerability.PrimaryLink = sr.PrimaryURL
197+
}
198+
if addFields.Score {
199+
vulnerability.Score = GetScoreFromCVSS(GetCvssV3(sr.CVSS))
200+
}
201+
if addFields.PURL && sr.PkgIdentifier.PURL != nil {
167202
vulnerability.PkgPURL = sr.PkgIdentifier.PURL.String()
168203
}
169204

0 commit comments

Comments
 (0)