Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow explicitly ignoring the license of a package in config #1243

Merged
merged 4 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
overriding license for package Alpine/apk-tools/2.12.10-r1 with UNKNOWN
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
ignoring license for package Alpine/musl/1.2.3-r4
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 | apk-tools | 2.12.10-r1 | 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
23 changes: 23 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,23 @@
[[PackageOverrides]]
ecosystem = "npm"
ignore = true
license.override = ["0BSD"]

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

[[PackageOverrides]]
ecosystem = "Alpine"
name = "apk-tools"
license.ignore = true
license.override = ["UNKNOWN"] # this takes priority over license.ignore
G-Rath marked this conversation as resolved.
Show resolved Hide resolved

[[PackageOverrides]]
ecosystem = "Alpine"
name = "musl"
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
5 changes: 3 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ ecosystem = "Go"
group = "dev"

# Actions to take for matching packages:
ignore = true # Ignore this package entirely, including license scanning
license.override = ["MIT", "0BSD"] # Override the license of the package, if it is not ignored
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 completely ignored at the top level
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I've purposely kept the documentation here light as I think it'll be easier to document once #1226 is landed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
license.override = ["MIT", "0BSD"] # Override the license of the package, if it is not completely ignored at the top level
license.override = ["MIT", "0BSD"] # Override the license of the package, if it is not completely ignored

I think this should be updated now that ignore takes priority.


effectiveUntil = 2022-11-09 # Optional exception expiry date, after which the override will no longer apply
reason = "abc" # Optional reason for the override, to explain why it was added
Expand Down
3 changes: 2 additions & 1 deletion 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 @@ -112,7 +113,7 @@ 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
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
7 changes: 6 additions & 1 deletion pkg/osvscanner/vulnerability_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ func buildVulnerabilityResults(
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, ","))
// reaching here without any override licenses means that the license should be ignored completely
if len(overrideLicenses) == 0 {
r.Infof("ignoring license for package %s/%s/%s\n", pkg.Package.Ecosystem, pkg.Package.Name, pkg.Package.Version)
G-Rath marked this conversation as resolved.
Show resolved Hide resolved
} else {
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, ","))
G-Rath marked this conversation as resolved.
Show resolved Hide resolved
}
licensesResp[i] = overrideLicenses
}
if len(actions.ScanLicensesAllowlist) > 0 {
Expand Down