diff --git a/docs/schema.md b/docs/schema.md index 0e8bd88a..375382c2 100644 --- a/docs/schema.md +++ b/docs/schema.md @@ -887,6 +887,11 @@ strings in the table below. The `name` field is a string identifying the library within its ecosystem. The two fields must both be present, because the `ecosystem` serves to define the interpretation of the `name`. +Use the wildcard package name `*` to indicate that an advisory affects all +packages within the specified `ecosystem`. For example, this is useful when an +ecosystem version reaches end-of-life (EOL) and receives no further security +support. + The `purl` field is a string following the [Package URL specification](https://github.com/package-url/purl-spec) that identifies the package, without the `@version` component. diff --git a/tools/osv-linter/internal/checks/packages.go b/tools/osv-linter/internal/checks/packages.go index ffb6deee..8b372a9e 100644 --- a/tools/osv-linter/internal/checks/packages.go +++ b/tools/osv-linter/internal/checks/packages.go @@ -44,6 +44,9 @@ func PackageExists(json *gjson.Result, config *Config) (findings []CheckError) { return true // keep iterating (over affected entries) } pkg := value.Get("package.name").String() + if pkg == "*" { + return true // keep iterating, wildcard package matches everything and doesn't need to exist + } // Avoid unnecessary network traffic for repeat packages. if _, ok := knownExistent[Package{Ecosystem: ecosystem, Name: pkg}]; ok { @@ -92,6 +95,9 @@ func PackageVersionsExist(json *gjson.Result, config *Config) (findings []CheckE return true // keep iterating (over affected entries) } pkg := value.Get("package.name").String() + if pkg == "*" { + return true // keep iterating, wildcard package matches everything and doesn't need to exist + } versionsToCheck := []string{} // Examine versions in ranges. maybeRanges := value.Get("ranges") diff --git a/tools/osv-linter/internal/checks/packages_test.go b/tools/osv-linter/internal/checks/packages_test.go index 4e992994..2709bb5b 100644 --- a/tools/osv-linter/internal/checks/packages_test.go +++ b/tools/osv-linter/internal/checks/packages_test.go @@ -27,6 +27,14 @@ func TestPackageExists(t *testing.T) { }, wantFindings: []CheckError{{Code: "", Message: "package \"123bla\" not found in \"PyPI\""}}, }, + { + name: "Wildcard package name in PyPI", + args: args{ + json: LoadTestData("../../testdata/wildcard-package.json"), + config: &Config{}, + }, + wantFindings: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -63,6 +71,14 @@ func TestPackageVersionsExists(t *testing.T) { config: &Config{Ecosystems: []string{"npm"}}, }, }, + { + name: "Wildcard package versions check", + args: args{ + json: LoadTestData("../../testdata/wildcard-package.json"), + config: &Config{}, + }, + wantFindings: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/tools/osv-linter/testdata/wildcard-package.json b/tools/osv-linter/testdata/wildcard-package.json new file mode 100644 index 00000000..bd12c351 --- /dev/null +++ b/tools/osv-linter/testdata/wildcard-package.json @@ -0,0 +1,19 @@ +{ + "modified": "2026-06-10T00:00:00Z", + "published": "2026-06-10T00:00:00Z", + "schema_version": "1.5.0", + "id": "CVE-2026-99999", + "summary": "Ecosystem wildcard test", + "details": "This is a test case for a wildcard package name.", + "affected": [ + { + "package": { + "ecosystem": "PyPI", + "name": "*" + }, + "versions": [ + "1.0.0" + ] + } + ] +}