Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Keeps security report resources updated
| 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. |
| 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 |
| tolerations | list | `[]` | tolerations set the operator tolerations |
| 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 |
| 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, -Title, -PrimaryLink, -Score and -PkgPURL. |
| trivy.clientServerSkipUpdate | bool | `false` | clientServerSkipUpdate is the flag to enable skip databases update for Trivy client. Only applicable in ClientServer mode. |
| 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). |
| 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). |
Expand Down
3 changes: 2 additions & 1 deletion deploy/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ trivy:
priorityClassName: ""

# -- 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
# 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, -Title, -PrimaryLink, -Score and -PkgPURL.
additionalVulnerabilityReportFields: ""

# -- httpProxy is the HTTP proxy used by Trivy to download the vulnerabilities database from GitHub.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/vulnerability-scanning/trivy.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ EOF
| `trivy.javaDbRepository` | `mirror.gcr.io/aquasec/trivy-java-db` | External OCI Registry to download the vulnerability database for Java |
| `trivy.dbRepositoryInsecure` | `false` | The Flag to enable insecure connection for downloading trivy-db via proxy (air-gaped env) |
| `trivy.mode` | `Standalone` | Trivy client mode. Either `Standalone` or `ClientServer`. Depending on the active mode other settings might be applicable or required. |
| `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 |
| `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,Title,PrimaryLink,Score,PkgPURL` |
| `trivy.command` | `image` | command. One of `image`, `filesystem` or `rootfs` scanning. Depending on the target type required for the scan. |
| `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 |
| `trivy.severity` | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | A comma separated list of severity levels reported by Trivy |
Expand Down
37 changes: 29 additions & 8 deletions pkg/plugins/trivy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,49 @@ type Config struct {
}

func (c Config) GetAdditionalVulnerabilityReportFields() vulnerabilityreport.AdditionalFields {
addFields := vulnerabilityreport.AdditionalFields{}
addFields := vulnerabilityreport.NewDefaultAdditionalFields()

fields, ok := c.Data[keyTrivyAdditionalVulnerabilityReportFields]
if !ok {
return addFields
}
for _, field := range strings.Split(fields, ",") {
trimmed_field := strings.TrimSpace(field)
value := !strings.HasPrefix(trimmed_field, "-")
field = strings.TrimPrefix(trimmed_field, "-")
switch strings.TrimSpace(field) {
case "Resource":
addFields.Resource = value
case "InstalledVersion":
addFields.InstalledVersion = value
case "FixedVersion":
addFields.FixedVersion = value
case "PublishedDate":
addFields.PublishedDate = value
case "LastModifiedDate":
addFields.LastModifiedDate = value
case "Title":
addFields.Title = value
case "PrimaryLink":
addFields.PrimaryLink = value
case "Score":
addFields.Score = value
case "PkgPURL":
addFields.PkgPURL = value
case "Description":
addFields.Description = true
addFields.Description = value
case "Links":
addFields.Links = true
addFields.Links = value
case "CVSS":
addFields.CVSS = true
addFields.CVSS = value
case "Target":
addFields.Target = true
addFields.Target = value
case "Class":
addFields.Class = true
addFields.Class = value
case "PackageType":
addFields.PackageType = true
addFields.PackageType = value
case "PackagePath":
addFields.PkgPath = true
addFields.PkgPath = value
}
}
return addFields
Expand Down
86 changes: 81 additions & 5 deletions pkg/plugins/trivy/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
{
name: "no additional fields are set",
configData: Config{PluginConfig: trivyoperator.PluginConfig{}},
additionalFields: vulnerabilityreport.AdditionalFields{},
additionalFields: vulnerabilityreport.NewDefaultAdditionalFields(),
},
{
name: "all additional fields are set",
Expand All @@ -97,7 +97,25 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
"trivy.additionalVulnerabilityReportFields": "PackageType,PkgPath,Class,Target,Links,Description,CVSS",
},
}},
additionalFields: vulnerabilityreport.AdditionalFields{Description: true, Links: true, CVSS: true, Class: true, PackageType: true, PkgPath: true, Target: true},
additionalFields: vulnerabilityreport.AdditionalFields{
// default
Resource: true,
InstalledVersion: true,
FixedVersion: true,
PublishedDate: true,
LastModifiedDate: true,
Title: true,
PrimaryLink: true,
Score: true,
PkgPURL: true,
// added
Description: true,
Links: true,
CVSS: true,
Class: true,
PackageType: true,
Target: true,
},
},
{
name: "some additional fields are set",
Expand All @@ -106,19 +124,77 @@ func TestConfig_GetAdditionalVulnerabilityReportFields(t *testing.T) {
"trivy.additionalVulnerabilityReportFields": "PackageType,Target,Links,CVSS",
},
}},
additionalFields: vulnerabilityreport.AdditionalFields{Links: true, CVSS: true, PackageType: true, Target: true},
additionalFields: vulnerabilityreport.AdditionalFields{
// default
Resource: true,
InstalledVersion: true,
FixedVersion: true,
PublishedDate: true,
LastModifiedDate: true,
Title: true,
PrimaryLink: true,
Score: true,
PkgPURL: true,
// added
Links: true,
CVSS: true,
PackageType: true,
Target: true,
},
},
{
name: "all fields are removed",
configData: Config{PluginConfig: trivyoperator.PluginConfig{
Data: map[string]string{
"trivy.additionalVulnerabilityReportFields": " -Resource,- InstalledVersion, - FixedVersion, - PublishedDate,-LastModifiedDate,-Title,-PrimaryLink,-Score,-PkgPURL",
},
}},
additionalFields: vulnerabilityreport.AdditionalFields{},
},
{
name: "some fields are added and some are removed",
configData: Config{PluginConfig: trivyoperator.PluginConfig{
Data: map[string]string{
"trivy.additionalVulnerabilityReportFields": "CVSS,PackageType,-PublishedDate,-LastModifiedDate",
},
}},
additionalFields: vulnerabilityreport.AdditionalFields{
// default
Resource: true,
InstalledVersion: true,
FixedVersion: true,
PublishedDate: false, // removed
LastModifiedDate: false, // removed
Title: true,
PrimaryLink: true,
Score: true,
PkgPURL: true,
// added
CVSS: true,
PackageType: true,
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
addFields := tc.configData.GetAdditionalVulnerabilityReportFields()
assert.Equal(t, tc.additionalFields.Resource, addFields.Resource)
assert.Equal(t, tc.additionalFields.InstalledVersion, addFields.InstalledVersion)
assert.Equal(t, tc.additionalFields.FixedVersion, addFields.FixedVersion)
assert.Equal(t, tc.additionalFields.PublishedDate, addFields.PublishedDate)
assert.Equal(t, tc.additionalFields.LastModifiedDate, addFields.LastModifiedDate)
assert.Equal(t, tc.additionalFields.Title, addFields.Title)
assert.Equal(t, tc.additionalFields.PrimaryLink, addFields.PrimaryLink)
assert.Equal(t, tc.additionalFields.Score, addFields.Score)
assert.Equal(t, tc.additionalFields.PkgPURL, addFields.PkgPURL)
assert.Equal(t, tc.additionalFields.Description, addFields.Description)
assert.Equal(t, tc.additionalFields.Links, addFields.Links)
assert.Equal(t, tc.additionalFields.CVSS, addFields.CVSS)
assert.Equal(t, tc.additionalFields.Target, addFields.Target)
assert.Equal(t, tc.additionalFields.PackageType, addFields.PackageType)
assert.Equal(t, tc.additionalFields.Class, addFields.Class)
assert.Equal(t, tc.additionalFields.Links, addFields.Links)
assert.Equal(t, tc.additionalFields.PackageType, addFields.PackageType)
assert.Equal(t, tc.additionalFields.PkgPath, addFields.PkgPath)
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugins/trivy/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ func (p *plugin) ParseReportData(ctx trivyoperator.PluginContext, imageRef strin
}
vulnerabilities := make([]v1alpha1.Vulnerability, 0)
secrets := make([]v1alpha1.ExposedSecret, 0)
addFields := config.GetAdditionalVulnerabilityReportFields()
for _, report := range reports.Results {
addFields := config.GetAdditionalVulnerabilityReportFields()
vulnerabilities = append(vulnerabilities, vulnerabilityreport.GetVulnerabilitiesFromScanResult(report, addFields)...)
secrets = append(secrets, getExposedSecretsFromScanResult(report)...)
}
Expand Down
83 changes: 57 additions & 26 deletions pkg/vulnerabilityreport/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,41 +129,72 @@ func (r *readWriter) FindByOwner(ctx context.Context, owner kube.ObjectRef) ([]v
}

type AdditionalFields struct {
Description bool
Links bool
CVSS bool
Target bool
Class bool
PackageType bool
PkgPath bool
Resource bool
InstalledVersion bool
FixedVersion bool
PublishedDate bool
LastModifiedDate bool
Title bool
PrimaryLink bool
Score bool
PkgPURL bool
Description bool
Links bool
CVSS bool
Target bool
Class bool
PackageType bool
PkgPath bool
}

func NewDefaultAdditionalFields() AdditionalFields {
return AdditionalFields{
Resource: true,
InstalledVersion: true,
FixedVersion: true,
PublishedDate: true,
LastModifiedDate: true,
Title: true,
PrimaryLink: true,
Score: true,
PkgPURL: true,
}
}

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

for _, sr := range report.Vulnerabilities {
var pd, lmd string
if sr.PublishedDate != nil {
pd = sr.PublishedDate.Format(time.RFC3339)
}
if sr.LastModifiedDate != nil {
lmd = sr.LastModifiedDate.Format(time.RFC3339)
}
vulnerability := v1alpha1.Vulnerability{
VulnerabilityID: sr.VulnerabilityID,
Resource: sr.PkgName,
InstalledVersion: sr.InstalledVersion,
FixedVersion: sr.FixedVersion,
PublishedDate: pd,
LastModifiedDate: lmd,
Severity: v1alpha1.Severity(sr.Severity),
Title: sr.Title,
PrimaryLink: sr.PrimaryURL,
Links: []string{},
Score: GetScoreFromCVSS(GetCvssV3(sr.CVSS)),
VulnerabilityID: sr.VulnerabilityID,
Severity: v1alpha1.Severity(sr.Severity),
}

if sr.PkgIdentifier.PURL != nil {
if addFields.Resource {
vulnerability.Resource = sr.PkgName
}
if addFields.InstalledVersion {
vulnerability.InstalledVersion = sr.InstalledVersion
}
if addFields.FixedVersion {
vulnerability.FixedVersion = sr.FixedVersion
}
if addFields.PublishedDate && sr.PublishedDate != nil {
vulnerability.PublishedDate = sr.PublishedDate.Format(time.RFC3339)
}
if addFields.LastModifiedDate && sr.LastModifiedDate != nil {
vulnerability.LastModifiedDate = sr.LastModifiedDate.Format(time.RFC3339)
}
if addFields.Title {
vulnerability.Title = sr.Title
}
if addFields.PrimaryLink {
vulnerability.PrimaryLink = sr.PrimaryURL
}
if addFields.Score {
vulnerability.Score = GetScoreFromCVSS(GetCvssV3(sr.CVSS))
}
if addFields.PkgPURL && sr.PkgIdentifier.PURL != nil {
vulnerability.PkgPURL = sr.PkgIdentifier.PURL.String()
}

Expand Down
Loading