Skip to content

bug: SeveritySource is empty when severity falls back to top-level Severity field from trivy-db #10409

@DmitriyLewen

Description

@DmitriyLewen

Description

When autoDetectSeverity exhausts all known VendorSeverity sources (data source ID + NVD fallback), it falls back to the top-level Severity field stored in trivy-db. However, trivy-db does not store origin metadata for this field, so SeveritySource is returned as an empty string and is missing from the output entirely.

Code path (pkg/vulnerability/vulnerability.go):

// autoDetectSeverity, lines 165-170
if vuln.Severity == "" {
    return dbTypes.SeverityUnknown.String(), ""
}
onceWarn()
return vuln.Severity, ""  // ← SeveritySource is always empty here

Root Cause

The top-level Severity field in trivy-db is computed by Normalize(): it iterates AllSourceIDs in priority order and picks the first source with a non-zero CVSS score or severity. The source that "won" is not stored alongside the field, so Trivy has no way to report it.

For example, CVE-2026-0861 has Severity: HIGH — not from RedHat's advisory rating (LOW), but from RedHat's CVSS V3 score of 8.1 (→ HIGH). This origin is invisible to Trivy.

Real-world Example

CVE-2026-0861 (glibc: Integer overflow in memalign) on Amazon Linux:

  • VendorSeverity has no amazon or nvd entry
  • Trivy falls back to vuln.Severity = "HIGH"
  • SeveritySource is missing from JSON output entirely

Reported in discussion #10217:

"this CVE has no SeveritySource value. In fact it doesn't even have
a SeveritySource property. All the other identified CVEs do."

Proposed Solutions

Option 1: Add SeveritySource to trivy-db (correct fix)

Add a SeveritySource types.SourceID field to types.Vulnerability in trivy-db, populated by Normalize() to record which source from AllSourceIDs contributed the top-level Severity.

Trivy's autoDetectSeverity then uses vuln.SeveritySource instead of returning "":

return vuln.Severity, vuln.SeveritySource

Pros: Accurate source tracking, no behavior change.
Cons: Requires coordinated changes in trivy-db + trivy, DB schema bump.

Option 2: Fall back to VendorSeverity in AllSourceIDs order (trivy-only fix)

Before falling back to vuln.Severity, iterate over AllSourceIDs and pick the first source present in VendorSeverity:

for _, source := range vulnerability.AllSourceIDs {
    if severity, ok := vuln.VendorSeverity[source]; ok {
        return severity.String(), source
    }
}

Pros: Self-contained trivy change, no trivy-db coordination needed.
Cons: May change the effective severity value. The top-level Severity field is computed with CVSS-first priority, while VendorSeverity uses advisory-first priority — they use opposite rules. For CVE-2026-0861, this fallback would return redhat=LOW instead of the current HIGH (computed from RedHat's CVSS V3 score 8.1). This inconsistency in trivy-db is tracked separately in aquasecurity/trivy-db#650.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.scan/vulnerabilityIssues relating to vulnerability scanning

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions