mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 07:40:48 -08:00
feat(report): support for filtering licenses and secrets via rego policy files (#6004)
This commit is contained in:
@@ -56,3 +56,21 @@ ignore {
|
||||
# https://cwe.mitre.org/data/definitions/352.html
|
||||
input.CweIDs[_] == "CWE-352"
|
||||
}
|
||||
|
||||
# Ignore a license
|
||||
ignore {
|
||||
input.PkgName == "alpine-baselayout"
|
||||
input.Name == "GPL-2.0"
|
||||
}
|
||||
|
||||
# Ignore loose file license
|
||||
ignore {
|
||||
input.Name == "AGPL-3.0"
|
||||
input.FilePath == "/usr/share/grafana/LICENSE"
|
||||
}
|
||||
|
||||
# Ignore secret
|
||||
ignore {
|
||||
input.RuleID == "aws-access-key-id"
|
||||
input.Match == "AWS_ACCESS_KEY_ID=\"********************\""
|
||||
}
|
||||
|
||||
@@ -409,8 +409,8 @@ Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
|
||||
|:----------------:|:---------:|
|
||||
| Vulnerability | ✓ |
|
||||
| Misconfiguration | ✓ |
|
||||
| Secret | |
|
||||
| License | |
|
||||
| Secret | ✓ |
|
||||
| License | ✓ |
|
||||
|
||||
!!! warning "EXPERIMENTAL"
|
||||
This feature might change without preserving backwards compatibility.
|
||||
@@ -455,7 +455,8 @@ trivy image -f json centos:7
|
||||
...
|
||||
```
|
||||
|
||||
Each individual vulnerability (under `Results.Vulnerabilities`) or Misconfiguration (under `Results.Misconfigurations`) is evaluated for exclusion or inclusion by the `ignore` rule.
|
||||
Each individual Vulnerability, Misconfiguration, License and Secret (under `Results.Vulnerabilities`, `Results.Misconfigurations`,
|
||||
`Results.Licenses`, `Results.Secrets`) is evaluated for exclusion or inclusion by the `ignore` rule.
|
||||
|
||||
The following is a Rego ignore policy that filters out every vulnerability with a specific CWE ID (as seen in the JSON example above):
|
||||
|
||||
|
||||
@@ -288,6 +288,34 @@ func applyPolicy(ctx context.Context, result *types.Result, policyFile string) e
|
||||
}
|
||||
result.Misconfigurations = filteredMisconfs
|
||||
|
||||
// Secrets
|
||||
var filteredSecrets []types.DetectedSecret
|
||||
for _, scrt := range result.Secrets {
|
||||
ignored, err := evaluate(ctx, query, scrt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ignored {
|
||||
continue
|
||||
}
|
||||
filteredSecrets = append(filteredSecrets, scrt)
|
||||
}
|
||||
result.Secrets = filteredSecrets
|
||||
|
||||
// Licenses
|
||||
var filteredLicenses []types.DetectedLicense
|
||||
for _, lic := range result.Licenses {
|
||||
ignored, err := evaluate(ctx, query, lic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ignored {
|
||||
continue
|
||||
}
|
||||
filteredLicenses = append(filteredLicenses, lic)
|
||||
}
|
||||
result.Licenses = filteredLicenses
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -615,6 +615,78 @@ func TestFilter(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ignore file for licenses and secrets",
|
||||
args: args{
|
||||
report: types.Report{
|
||||
Results: types.Results{
|
||||
{
|
||||
Licenses: []types.DetectedLicense{
|
||||
{
|
||||
Name: "GPL-3.0",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
FilePath: "usr/share/gcc/python/libstdcxx/v6/__init__.py",
|
||||
Category: "restricted",
|
||||
Confidence: 1,
|
||||
},
|
||||
{
|
||||
Name: "GPL-3.0",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
FilePath: "usr/share/gcc/python/libstdcxx/v6/printers.py",
|
||||
Category: "restricted",
|
||||
Confidence: 1,
|
||||
},
|
||||
},
|
||||
Secrets: []types.DetectedSecret{
|
||||
{
|
||||
RuleID: "generic-passed-rule",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
Title: "Secret should pass filter",
|
||||
StartLine: 1,
|
||||
EndLine: 2,
|
||||
Match: "*****",
|
||||
},
|
||||
{
|
||||
RuleID: "generic-ignored-rule",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
Title: "Secret should be ignored",
|
||||
StartLine: 3,
|
||||
EndLine: 4,
|
||||
Match: "*****",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
severities: []dbTypes.Severity{dbTypes.SeverityLow},
|
||||
policyFile: "./testdata/test-ignore-policy-licenses-and-secrets.rego",
|
||||
},
|
||||
want: types.Report{
|
||||
Results: types.Results{
|
||||
{
|
||||
Licenses: []types.DetectedLicense{
|
||||
{
|
||||
Name: "GPL-3.0",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
FilePath: "usr/share/gcc/python/libstdcxx/v6/__init__.py",
|
||||
Category: "restricted",
|
||||
Confidence: 1,
|
||||
},
|
||||
},
|
||||
Secrets: []types.DetectedSecret{
|
||||
{
|
||||
RuleID: "generic-passed-rule",
|
||||
Severity: dbTypes.SeverityLow.String(),
|
||||
Title: "Secret should pass filter",
|
||||
StartLine: 1,
|
||||
EndLine: 2,
|
||||
Match: "*****",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path with duplicates, one with empty fixed version",
|
||||
args: args{
|
||||
|
||||
15
pkg/result/testdata/test-ignore-policy-licenses-and-secrets.rego
vendored
Normal file
15
pkg/result/testdata/test-ignore-policy-licenses-and-secrets.rego
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package trivy
|
||||
|
||||
import data.lib.trivy
|
||||
|
||||
default ignore=false
|
||||
|
||||
ignore {
|
||||
input.Name == "GPL-3.0"
|
||||
input.FilePath == "usr/share/gcc/python/libstdcxx/v6/printers.py"
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.RuleID == "generic-ignored-rule"
|
||||
input.Title == "Secret should be ignored"
|
||||
}
|
||||
Reference in New Issue
Block a user