bug(license): license scanner silently drops licenses that fail SPDX parsing
Description
If a package license name can't be parsed as an SPDX expression (e.g. CDDL + GPLv2 with classpath exception or Apache License (2.0) with Commons Clause), Trivy doesn't report this license as a finding.
It is missing from the table, from Results[].Licenses in the JSON report, from SARIF and from the totals, even with --severity UNKNOWN, and nothing is logged about it.
Parsable but unclassified names are reported as unknown / UNKNOWN.
Originally reported in #11250.
Reproduction
sbom.cdx.json:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"components": [
{
"type": "library",
"name": "pkg-valid-spdx",
"version": "1.0.0",
"purl": "pkg:maven/example/[email protected]",
"licenses": [{ "license": { "id": "MIT" } }]
},
{
"type": "library",
"name": "pkg-cddl-gpl",
"version": "1.0.0",
"purl": "pkg:maven/example/[email protected]",
"licenses": [{ "license": { "name": "CDDL + GPLv2 with classpath exception" } }]
},
{
"type": "library",
"name": "pkg-commons-clause",
"version": "1.0.0",
"purl": "pkg:maven/example/[email protected]",
"licenses": [{ "license": { "name": "Apache License (2.0) with Commons Clause" } }]
}
]
}$ trivy sbom --scanners license -q sbom.cdx.jsonActual result
Only 1 of 3 licenses is reported:
Java (license)
==============
Total: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
┌────────────────────────┬─────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├────────────────────────┼─────────┼────────────────┼──────────┤
│ example:pkg-valid-spdx │ MIT │ notice │ LOW │
└────────────────────────┴─────────┴────────────────┴──────────┘Expected result
Unparsable names are reported as unknown / UNKNOWN:
Java (license)
==============
Total: 3 (UNKNOWN: 2, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
┌────────────────────────────┬──────────────────────────────────────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├────────────────────────────┼──────────────────────────────────────────┼────────────────┼──────────┤
│ example:pkg-cddl-gpl │ CDDL + GPLv2 with classpath exception │ unknown │ UNKNOWN │
├────────────────────────────┼──────────────────────────────────────────┤ │ │
│ example:pkg-commons-clause │ Apache License (2.0) with Commons Clause │ │ │
├────────────────────────────┼──────────────────────────────────────────┼────────────────┼──────────┤
│ example:pkg-valid-spdx │ MIT │ notice │ LOW │
└────────────────────────────┴──────────────────────────────────────────┴────────────────┴──────────┘Root cause
If expression.Normalize returns an error, Scanner.Scan returns the unknown category with an empty severity.
filterLicenses only keeps licenses whose severity is in --severity, and an empty string is never in that list.
In client/server mode these licenses are still shown as UNKNOWN, because the RPC conversion turns the empty severity into UNKNOWN.
Proposed fix
- Return the
UNKNOWNseverity for unparsable names, as is already done for unclassified names and for license texts inScanTextLicense. - Skip licenses with an empty name when scanning package licenses.
Such licenses appear, for example, for SPDX packages without the optional
licenseDeclaredfield (strings.Split("", ",")returns[""]). They are currently hidden by the same bug, and after step 1 they would becomeUNKNOWNfindings without a name that can't be evaluated.
Source: aquasecurity/trivy