Skip to content

Commit

Permalink
refactor: add warning if severity not from vendor (or NVD or GH) is u…
Browse files Browse the repository at this point in the history
…sed (#6726)

Signed-off-by: knqyf263 <[email protected]>
Co-authored-by: Teppei Fukuda <[email protected]>
  • Loading branch information
DmitriyLewen and knqyf263 committed Jun 19, 2024
1 parent f144e91 commit dfe757e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 11 deletions.
39 changes: 38 additions & 1 deletion docs/docs/scanner/vulnerability.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,44 @@ If the data source does not provide a severity, the severity is determined based
| 7.0-8.9 | High |
| 9.0-10.0 | Critical |

If the CVSS score is also not provided, it falls back to [NVD][nvd], and if NVD does not have severity, it will be UNKNOWN.
If the CVSS score is also not provided, it falls back to [NVD][nvd].

NVD and some vendors may delay severity analysis, while other vendors, such as Red Hat, are able to quickly evaluate and announce the severity of vulnerabilities.
To avoid marking too many vulnerabilities as "UNKNOWN" severity, Trivy uses severity ratings from other vendors when the NVD information is not yet available.
The order of preference for vendor severity data can be found [here](https://github.com/aquasecurity/trivy-db/blob/79d0fbd1e246f3c77eef4b9826fe4bf65940b221/pkg/vulnsrc/vulnerability/vulnerability.go#L17-L19).

You can reference `SeveritySource` in the [JSON reporting format](../configuration/reporting.md#json) to see from where the severity is taken for a given vulnerability.

```shell
"SeveritySource": "debian",
```


In addition, you can see all the vendor severity ratings.

```json
"VendorSeverity": {
"amazon": 2,
"cbl-mariner": 4,
"ghsa": 4,
"nvd": 4,
"photon": 4,
"redhat": 2,
"ubuntu": 2
}
```

Here is the severity mapping in Trivy:

| Number | Severity |
|:------:|----------|
| 0 | Unknown |
| 1 | Low |
| 2 | Medium |
| 3 | High |
| 4 | Critical |

If no vendor has a severity, the `UNKNOWN` severity will be used.

### Unfixed Vulnerabilities
The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution.
Expand Down
26 changes: 16 additions & 10 deletions pkg/vulnerability/vulnerability.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package vulnerability

import (
"strings"
"sync"

"github.com/google/wire"
"github.com/samber/lo"

"github.com/aquasecurity/trivy-db/pkg/db"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
Expand Down Expand Up @@ -46,6 +48,12 @@ var SuperSet = wire.NewSet(
NewClient,
)

// Show warning if we use severity from another vendor
// cf. https://github.com/aquasecurity/trivy/issues/6714
var onceWarn = sync.OnceFunc(func() {
log.Warn("Using severities from other vendors for some vulnerabilities. Read https://aquasecurity.github.io/trivy/latest/docs/scanner/vulnerability/#severity-selection for details.")
})

// Client manipulates vulnerabilities
type Client struct {
dbc db.Operation
Expand Down Expand Up @@ -77,13 +85,10 @@ func (c Client) FillInfo(vulns []types.DetectedVulnerability) {
}

// Detect the data source
var source dbTypes.SourceID
if vulns[i].DataSource != nil {
source = vulns[i].DataSource.ID
}
dataSource := lo.FromPtr(vulns[i].DataSource)

// Select the severity according to the detected source.
severity, severitySource := c.getVendorSeverity(vulnID, &vuln, source)
// Select the severity according to the detected sourceID.
severity, severitySource := c.getVendorSeverity(vulnID, &vuln, dataSource)

// The vendor might provide package-specific severity like Debian.
// For example, CVE-2015-2328 in Debian has "unimportant" for mongodb and "low" for pcre3.
Expand All @@ -105,13 +110,13 @@ func (c Client) FillInfo(vulns []types.DetectedVulnerability) {

vulns[i].Severity = severity
vulns[i].SeveritySource = severitySource
vulns[i].PrimaryURL = c.getPrimaryURL(vulnID, vuln.References, source)
vulns[i].PrimaryURL = c.getPrimaryURL(vulnID, vuln.References, dataSource.ID)
}
}

func (c Client) getVendorSeverity(vulnID string, vuln *dbTypes.Vulnerability, source dbTypes.SourceID) (string, dbTypes.SourceID) {
if vs, ok := vuln.VendorSeverity[source]; ok {
return vs.String(), source
func (c Client) getVendorSeverity(vulnID string, vuln *dbTypes.Vulnerability, dataSource dbTypes.DataSource) (string, dbTypes.SourceID) {
if vs, ok := vuln.VendorSeverity[dataSource.ID]; ok {
return vs.String(), dataSource.ID
}

// use severity from GitHub for all GHSA-xxx vulnerabilities
Expand All @@ -130,6 +135,7 @@ func (c Client) getVendorSeverity(vulnID string, vuln *dbTypes.Vulnerability, so
return dbTypes.SeverityUnknown.String(), ""
}

onceWarn()
return vuln.Severity, ""
}

Expand Down

0 comments on commit dfe757e

Please sign in to comment.