Skip to content

Commit

Permalink
feat: allow explicitly ignoring the license of a package in config (#…
Browse files Browse the repository at this point in the history
…1243)

This allows you to configure the scanner to completely ignore the
license of a package in a way that is explicit, as oppose to configuring
`license.overrides` to set the package license to an allowed one.

Resolves #1124
  • Loading branch information
G-Rath authored Sep 13, 2024
1 parent 308a7bf commit 19e0abe
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 11 deletions.
48 changes: 48 additions & 0 deletions cmd/osv-scanner/__snapshots__/main_test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,54 @@ Filtered 1 vulnerability from output

---

[TestRun_Licenses/Some_packages_with_ignored_licenses - 1]
Scanning dir ./fixtures/locks-many
Scanned <rootdir>/fixtures/locks-many/Gemfile.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/alpine.cdx.xml as CycloneDX SBOM and found 14 packages
Scanned <rootdir>/fixtures/locks-many/composer.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/package-lock.json file and found 1 package
Scanned <rootdir>/fixtures/locks-many/yarn.lock file and found 1 package
Scanning dir ./fixtures/locks-insecure
Scanned <rootdir>/fixtures/locks-insecure/composer.lock file and found 1 package
Package npm/ansi-html/0.0.1 has been filtered out because:
Package npm/balanced-match/1.0.2 has been filtered out because:
Filtered 2 ignored package/s from the scan.
ignoring license for package Alpine/alpine-baselayout/3.4.0-r0
ignoring license for package Alpine/alpine-baselayout-data/3.4.0-r0
ignoring license for package Alpine/alpine-keys/2.4-r1
ignoring license for package Alpine/apk-tools/2.12.10-r1
ignoring license for package Alpine/busybox-binsh/1.36.1-r27
ignoring license for package Alpine/ca-certificates-bundle/20220614-r4
ignoring license for package Alpine/libc-utils/0.7.2-r3
ignoring license for package Alpine/libcrypto3/3.0.8-r0
ignoring license for package Alpine/libssl3/3.0.8-r0
overriding license for package Alpine/musl/1.2.3-r4 with UNKNOWN
ignoring license for package Alpine/musl-utils/1.2.3-r4
ignoring license for package Alpine/scanelf/1.3.5-r1
ignoring license for package Alpine/ssl_client/1.36.1-r27
ignoring license for package Alpine/zlib/1.2.13-r0
overriding license for package Packagist/sentry/sdk/2.0.4 with 0BSD
overriding license for package Packagist/league/flysystem/1.0.8 with 0BSD
+-------------------------------------+------+-----------+------------------+---------+---------------------------------------+
| OSV URL | CVSS | ECOSYSTEM | PACKAGE | VERSION | SOURCE |
+-------------------------------------+------+-----------+------------------+---------+---------------------------------------+
| https://osv.dev/GHSA-9f46-5r25-5wfm | 9.8 | Packagist | league/flysystem | 1.0.8 | fixtures/locks-insecure/composer.lock |
+-------------------------------------+------+-----------+------------------+---------+---------------------------------------+
+-------------------+-----------+------------------+----------+---------------------------------------+
| LICENSE VIOLATION | ECOSYSTEM | PACKAGE | VERSION | SOURCE |
+-------------------+-----------+------------------+----------+---------------------------------------+
| 0BSD | Packagist | league/flysystem | 1.0.8 | fixtures/locks-insecure/composer.lock |
| UNKNOWN | RubyGems | ast | 2.4.2 | fixtures/locks-many/Gemfile.lock |
| UNKNOWN | Alpine | musl | 1.2.3-r4 | fixtures/locks-many/alpine.cdx.xml |
| 0BSD | Packagist | sentry/sdk | 2.0.4 | fixtures/locks-many/composer.lock |
+-------------------+-----------+------------------+----------+---------------------------------------+

---

[TestRun_Licenses/Some_packages_with_ignored_licenses - 2]

---

[TestRun_Licenses/Some_packages_with_license_violations_and_show-all-packages_in_json - 1]
{
"results": [
Expand Down
28 changes: 28 additions & 0 deletions cmd/osv-scanner/fixtures/osv-scanner-complex-licenses-config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[[PackageOverrides]]
ecosystem = "npm"
ignore = true
license.override = ["0BSD"]

[[PackageOverrides]]
ecosystem = "Packagist"
license.override = ["0BSD"]

[[PackageOverrides]]
ecosystem = "Alpine"
name = "musl"
license.override = ["UNKNOWN"]

[[PackageOverrides]]
ecosystem = "Alpine"
name = "musl-utils"
license.ignore = true # this takes priority over license.override
license.override = ["UNKNOWN"]

[[PackageOverrides]]
ecosystem = "Alpine"
name = "apk-tools"
license.ignore = false

[[PackageOverrides]]
ecosystem = "Alpine"
license.ignore = true
5 changes: 5 additions & 0 deletions cmd/osv-scanner/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,11 @@ func TestRun_Licenses(t *testing.T) {
args: []string{"", "--format=json", "--experimental-licenses", "MIT", "--experimental-all-packages", "./fixtures/locks-licenses/package-lock.json"},
exit: 1,
},
{
name: "Some packages with ignored licenses",
args: []string{"", "--config=./fixtures/osv-scanner-complex-licenses-config.toml", "--experimental-licenses", "MIT", "./fixtures/locks-many", "./fixtures/locks-insecure"},
exit: 1,
},
{
name: "Some packages with license violations in json",
args: []string{"", "--format=json", "--experimental-licenses", "MIT", "./fixtures/locks-licenses/package-lock.json"},
Expand Down
3 changes: 2 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ ecosystem = "Go"
group = "dev"

# Actions to take for matching packages:
ignore = true # Ignore this package entirely, including license scanning
ignore = true # Ignore this package completely, including license scanning
license.ignore = true # Ignore the license of the package, if it is not already completely ignored at the top level
license.override = ["MIT", "0BSD"] # Override the license of the package, if it is not ignored

effectiveUntil = 2022-11-09 # Optional exception expiry date, after which the override will no longer apply
Expand Down
5 changes: 3 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (e PackageOverrideEntry) matches(pkg models.PackageVulns) bool {

type License struct {
Override []string `toml:"override"`
Ignore bool `toml:"ignore"`
}

func (c *Config) ShouldIgnore(vulnID string) (bool, IgnoreEntry) {
Expand Down Expand Up @@ -109,10 +110,10 @@ func (c *Config) ShouldIgnorePackageVersion(name, version, ecosystem string) (bo
})
}

// ShouldOverridePackageLicense determines if the given package should have its license changed based on override entries in the config
// ShouldOverridePackageLicense determines if the given package should have its license ignored or changed based on override entries in the config
func (c *Config) ShouldOverridePackageLicense(pkg models.PackageVulns) (bool, PackageOverrideEntry) {
return c.filterPackageVersionEntries(pkg, func(e PackageOverrideEntry) bool {
return len(e.License.Override) > 0
return e.License.Ignore || len(e.License.Override) > 0
})
}

Expand Down
95 changes: 92 additions & 3 deletions pkg/config/config_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ func TestConfig_ShouldOverridePackageLicense(t *testing.T) {
wantEntry PackageOverrideEntry
}{
{
name: "Exact version entry exists",
name: "Exact version entry exists with override",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Expand Down Expand Up @@ -809,7 +809,40 @@ func TestConfig_ShouldOverridePackageLicense(t *testing.T) {
},
},
{
name: "Version entry doesn't exist",
name: "Exact version entry exists with ignore",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Name: "lib1",
Version: "1.0.0",
Ecosystem: "Go",
License: License{
Ignore: true,
},
Reason: "abc",
},
},
},
args: models.PackageVulns{
Package: models.PackageInfo{
Name: "lib1",
Version: "1.0.0",
Ecosystem: "Go",
},
},
wantOk: true,
wantEntry: PackageOverrideEntry{
Name: "lib1",
Version: "1.0.0",
Ecosystem: "Go",
License: License{
Ignore: true,
},
Reason: "abc",
},
},
{
name: "Version entry doesn't exist with override",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Expand All @@ -834,7 +867,32 @@ func TestConfig_ShouldOverridePackageLicense(t *testing.T) {
wantEntry: PackageOverrideEntry{},
},
{
name: "Name matches",
name: "Version entry doesn't exist with ignore",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Name: "lib1",
Version: "1.0.0",
Ecosystem: "Go",
License: License{
Ignore: true,
},
Reason: "abc",
},
},
},
args: models.PackageVulns{
Package: models.PackageInfo{
Name: "lib1",
Version: "1.0.1",
Ecosystem: "Go",
},
},
wantOk: false,
wantEntry: PackageOverrideEntry{},
},
{
name: "Name matches with override",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Expand Down Expand Up @@ -864,6 +922,37 @@ func TestConfig_ShouldOverridePackageLicense(t *testing.T) {
Reason: "abc",
},
},
{
name: "Name matches with ignore",
config: Config{
PackageOverrides: []PackageOverrideEntry{
{
Name: "lib1",
Ecosystem: "Go",
License: License{
Ignore: true,
},
Reason: "abc",
},
},
},
args: models.PackageVulns{
Package: models.PackageInfo{
Name: "lib1",
Version: "1.0.1",
Ecosystem: "Go",
},
},
wantOk: true,
wantEntry: PackageOverrideEntry{
Name: "lib1",
Ecosystem: "Go",
License: License{
Ignore: true,
},
Reason: "abc",
},
},
}

for _, tt := range tests {
Expand Down
15 changes: 10 additions & 5 deletions pkg/osvscanner/vulnerability_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ func buildVulnerabilityResults(
if actions.ScanLicensesSummary || len(actions.ScanLicensesAllowlist) > 0 {
configToUse := configManager.Get(r, rawPkg.Source.Path)
if override, entry := configToUse.ShouldOverridePackageLicense(pkg); override {
overrideLicenses := make([]models.License, len(entry.License.Override))
for j, license := range entry.License.Override {
overrideLicenses[j] = models.License(license)
if entry.License.Ignore {
r.Infof("ignoring license for package %s/%s/%s\n", pkg.Package.Ecosystem, pkg.Package.Name, pkg.Package.Version)
licensesResp[i] = nil
} else {
overrideLicenses := make([]models.License, len(entry.License.Override))
for j, license := range entry.License.Override {
overrideLicenses[j] = models.License(license)
}
r.Infof("overriding license for package %s/%s/%s with %s\n", pkg.Package.Ecosystem, pkg.Package.Name, pkg.Package.Version, strings.Join(entry.License.Override, ","))
licensesResp[i] = overrideLicenses
}
r.Infof("overriding license for package %s/%s/%s with %s\n", pkg.Package.Ecosystem, pkg.Package.Name, pkg.Package.Version, strings.Join(entry.License.Override, ","))
licensesResp[i] = overrideLicenses
}
if len(actions.ScanLicensesAllowlist) > 0 {
pkg.Licenses = licensesResp[i]
Expand Down

0 comments on commit 19e0abe

Please sign in to comment.