diff --git a/bindings/go/osvschema/constants.go b/bindings/go/osvschema/constants.go
index 9462838f..b8d45743 100644
--- a/bindings/go/osvschema/constants.go
+++ b/bindings/go/osvschema/constants.go
@@ -17,6 +17,7 @@ const (
EcosystemCRAN Ecosystem = "CRAN"
EcosystemCratesIO Ecosystem = "crates.io"
EcosystemDebian Ecosystem = "Debian"
+ EcosystemDrupal Ecosystem = "Drupal"
EcosystemGHC Ecosystem = "GHC"
EcosystemGitHubActions Ecosystem = "GitHub Actions"
EcosystemGo Ecosystem = "Go"
diff --git a/docs/schema.md b/docs/schema.md
index 34628c7b..6c25e5df 100644
--- a/docs/schema.md
+++ b/docs/schema.md
@@ -245,6 +245,17 @@ The defined database prefixes and their "home" databases are:
+
+ DRUPAL |
+ Drupal Advisory Database (provided by Ackama) |
+
+
+ |
+
ELA |
Debian Extended LTS Security Advisories (provided by Freexian) |
@@ -790,6 +801,7 @@ The defined ecosystems are:
| `CRAN` | The R package ecosystem. The `name` is an R package name. |
| `crates.io` | The crates.io ecosystem for Rust; the `name` field is a crate name. |
| `Debian` | The Debian package ecosystem; the `name` is the name of the source package. The ecosystem string might optionally have a `:` suffix to scope the package to a particular Debian release. `` is a numeric version specified in the [Debian distro-info-data](https://debian.pages.debian.net/distro-info-data/debian.csv). For example, the ecosystem string "Debian:7" refers to the Debian 7 (wheezy) release. |
+| `Drupal` | The Drupal CMS ecosystem, for packages sourced from the Drupal composer repository. The ecosystem implies https://packages.drupal.org/8 as the source repository, unless a :7 suffix is present in which case the repository is https://packages.drupal.org/7 |
| `GHC` | The Haskell compiler ecosystem. The `name` field is the name of a component of the GHC compiler ecosystem (e.g., compiler, GHCI, RTS). |
| `GitHub Actions` | The GitHub Actions ecosystem; the `name` field is the action's repository name with owner e.g. `{owner}/{repo}`. |
| `Go` | The Go ecosystem; the `name` field is a Go module path. |
diff --git a/ecosystems.json b/ecosystems.json
index c5fb7ce1..547bb4ff 100644
--- a/ecosystems.json
+++ b/ecosystems.json
@@ -11,6 +11,7 @@
"CRAN": "The R package ecosystem. The `name` is an R package name.",
"crates.io": "The crates.io ecosystem for Rust; the `name` field is a crate name.",
"Debian": "The Debian package ecosystem; the `name` is the name of the source package. The ecosystem string might optionally have a `:` suffix to scope the package to a particular Debian release. `` is a numeric version specified in the [Debian distro-info-data](https://debian.pages.debian.net/distro-info-data/debian.csv). For example, the ecosystem string \"Debian:7\" refers to the Debian 7 (wheezy) release.",
+ "Drupal": "The Drupal CMS ecosystem, for packages sourced from the Drupal composer repository. The ecosystem implies https://packages.drupal.org/8 as the source repository, unless a :7 suffix is present in which case the repository is https://packages.drupal.org/7",
"GHC": "The Haskell compiler ecosystem. The `name` field is the name of a component of the GHC compiler ecosystem (e.g., compiler, GHCI, RTS).",
"GitHub Actions": "The GitHub Actions ecosystem; the `name` field is the action's repository name with owner e.g. `{owner}/{repo}`.",
"Go": "The Go ecosystem; the `name` field is a Go module path.",
diff --git a/tools/osv-linter/internal/checks/packages.go b/tools/osv-linter/internal/checks/packages.go
index c8358e80..130d77c1 100644
--- a/tools/osv-linter/internal/checks/packages.go
+++ b/tools/osv-linter/internal/checks/packages.go
@@ -37,9 +37,14 @@ func PackageExists(json *gjson.Result, config *Config) (findings []CheckError) {
if !maybePackage.Exists() {
return true // keep iterating (over affected entries)
}
- // Normalize ecosystems with a colon to their base.
+ ecosystem := value.Get("package.ecosystem").String()
+
+ // Normalize ecosystems with a colon to their base, except for the Drupal ecosystem
+ // as different repositories are used depending on the suffix
// e.g. "Alpine:v3.5" -> "Alpine"
- ecosystem := strings.Split(value.Get("package.ecosystem").String(), ":")[0]
+ if !strings.HasPrefix(ecosystem, "Drupal") {
+ ecosystem = strings.Split(ecosystem, ":")[0]
+ }
// Use config.Ecosystems as an allowlist, if it is set.
if len(config.Ecosystems) > 0 && !slices.Contains(config.Ecosystems, ecosystem) {
return true // keep iterating (over affected entries)
diff --git a/tools/osv-linter/internal/checks/schema_generated.json b/tools/osv-linter/internal/checks/schema_generated.json
index b30a9ef6..0cea599e 100644
--- a/tools/osv-linter/internal/checks/schema_generated.json
+++ b/tools/osv-linter/internal/checks/schema_generated.json
@@ -341,6 +341,7 @@
"CRAN",
"crates.io",
"Debian",
+ "Drupal",
"GHC",
"GitHub Actions",
"Go",
@@ -377,13 +378,13 @@
"type": "string",
"title": "Currently supported ecosystems",
"description": "These ecosystems are also documented at https://ossf.github.io/osv-schema/#affectedpackage-field",
- "pattern": "^(AlmaLinux|Alpaquita|Alpine|Android|BellSoft Hardened Containers|Bioconductor|Bitnami|Chainguard|ConanCenter|CRAN|crates\\.io|Debian|GHC|GitHub Actions|Go|Hackage|Hex|Kubernetes|Linux|Mageia|Maven|MinimOS|npm|NuGet|openEuler|openSUSE|OSS-Fuzz|Packagist|Photon OS|Pub|PyPI|Red Hat|Rocky Linux|RubyGems|SUSE|SwiftURL|Ubuntu|Wolfi|GIT)(:.+)?$"
+ "pattern": "^(AlmaLinux|Alpaquita|Alpine|Android|BellSoft Hardened Containers|Bioconductor|Bitnami|Chainguard|ConanCenter|CRAN|crates\\.io|Debian|Drupal|GHC|GitHub Actions|Go|Hackage|Hex|Kubernetes|Linux|Mageia|Maven|MinimOS|npm|NuGet|openEuler|openSUSE|OSS-Fuzz|Packagist|Photon OS|Pub|PyPI|Red Hat|Rocky Linux|RubyGems|SUSE|SwiftURL|Ubuntu|Wolfi|GIT)(:.+)?$"
},
"prefix": {
"type": "string",
"title": "Currently supported home database identifier prefixes",
"description": "These home databases are also documented at https://ossf.github.io/osv-schema/#id-modified-fields",
- "pattern": "^(ASB-A|PUB-A|ALSA|ALBA|ALEA|BELL|BIT|CGA|CURL|CVE|DSA|DLA|ELA|DTSA|GHSA|GO|GSD|HSEC|KUBE|LBSEC|LSN|MAL|MINI|MGASA|OESA|OSV|openSUSE-SU|PHSA|PSF|PYSEC|RHBA|RHEA|RHSA|RLSA|RXSA|RSEC|RUSTSEC|SUSE-[SRFO]U|UBUNTU|USN|V8)-"
+ "pattern": "^(ASB-A|PUB-A|ALSA|ALBA|ALEA|BELL|BIT|CGA|CURL|CVE|DSA|DLA|DRUPAL|ELA|DTSA|GHSA|GO|GSD|HSEC|KUBE|LBSEC|LSN|MAL|MINI|MGASA|OESA|OSV|openSUSE-SU|PHSA|PSF|PYSEC|RHBA|RHEA|RHSA|RLSA|RXSA|RSEC|RUSTSEC|SUSE-[SRFO]U|UBUNTU|USN|V8)-"
},
"severity": {
"type": [
diff --git a/tools/osv-linter/internal/pkgchecker/ecosystems.go b/tools/osv-linter/internal/pkgchecker/ecosystems.go
index 7ff9c99b..c7424d5e 100644
--- a/tools/osv-linter/internal/pkgchecker/ecosystems.go
+++ b/tools/osv-linter/internal/pkgchecker/ecosystems.go
@@ -13,6 +13,7 @@ var SupportedEcosystems = []string{
"NuGet",
"RubyGems",
"Packagist",
+ "Drupal",
"Pub",
"Hackage",
"Maven",
@@ -27,6 +28,7 @@ var EcosystemBaseURLs = map[string]string{
"NuGet": "https://api.nuget.org/v3-flatcontainer",
"RubyGems": "https://rubygems.org/api/v1/gems",
"Packagist": "https://repo.packagist.org/p2",
+ "Drupal": "https://packages.drupal.org/files/packages/8/p2",
"Pub": "https://pub.dev/api/packages",
"Hackage": "https://hackage.haskell.org/package",
"Maven": "https://search.maven.org/solrsearch/select",
@@ -51,6 +53,10 @@ func ExistsInEcosystem(pkg string, ecosystem string) bool {
return existsInCrates(pkg)
case "Debian":
return true
+ case "Drupal":
+ return existsInDrupal(pkg)
+ case "Drupal:7":
+ return true
case "GIT":
return true
case "GitHub Actions":
@@ -136,6 +142,8 @@ func VersionsExistInEcosystem(pkg string, versions []string, ecosystem string) e
return nil
case "Debian":
return nil
+ case "Drupal":
+ return nil
case "GIT":
return nil
case "GitHub Actions":
diff --git a/tools/osv-linter/internal/pkgchecker/package_check.go b/tools/osv-linter/internal/pkgchecker/package_check.go
index 13d2d030..676decb2 100644
--- a/tools/osv-linter/internal/pkgchecker/package_check.go
+++ b/tools/osv-linter/internal/pkgchecker/package_check.go
@@ -86,6 +86,13 @@ func existsInPackagist(pkg string) bool {
return checkPackageExists(packageInstanceURL)
}
+// Validate the existence of a package in Packagist.
+func existsInDrupal(pkg string) bool {
+ packageInstanceURL := fmt.Sprintf("%s/%s.json", EcosystemBaseURLs["Drupal"], pkg)
+
+ return checkPackageExists(packageInstanceURL)
+}
+
// Validate the existence of a package in PyPI.
func existsInPyPI(pkg string) bool {
ecosystem := "PyPI"
diff --git a/tools/osv-linter/internal/pkgchecker/package_check_test.go b/tools/osv-linter/internal/pkgchecker/package_check_test.go
index 809bf71b..e1f44756 100644
--- a/tools/osv-linter/internal/pkgchecker/package_check_test.go
+++ b/tools/osv-linter/internal/pkgchecker/package_check_test.go
@@ -144,6 +144,33 @@ func Test_existsInPackagist(t *testing.T) {
}
}
+func Test_existsInDrupal(t *testing.T) {
+ tests := []struct {
+ name string
+ pkg string
+ want bool
+ ver string
+ }{
+ {
+ name: "existing package",
+ pkg: "drupal/tfa",
+ want: true,
+ },
+ {
+ name: "non-existing package",
+ pkg: "non-existing-package",
+ want: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := existsInDrupal(tt.pkg); got != tt.want {
+ t.Errorf("existsInDrupal() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
func Test_existsInPub(t *testing.T) {
tests := []struct {
name string
diff --git a/validation/schema.json b/validation/schema.json
index b30a9ef6..0cea599e 100644
--- a/validation/schema.json
+++ b/validation/schema.json
@@ -341,6 +341,7 @@
"CRAN",
"crates.io",
"Debian",
+ "Drupal",
"GHC",
"GitHub Actions",
"Go",
@@ -377,13 +378,13 @@
"type": "string",
"title": "Currently supported ecosystems",
"description": "These ecosystems are also documented at https://ossf.github.io/osv-schema/#affectedpackage-field",
- "pattern": "^(AlmaLinux|Alpaquita|Alpine|Android|BellSoft Hardened Containers|Bioconductor|Bitnami|Chainguard|ConanCenter|CRAN|crates\\.io|Debian|GHC|GitHub Actions|Go|Hackage|Hex|Kubernetes|Linux|Mageia|Maven|MinimOS|npm|NuGet|openEuler|openSUSE|OSS-Fuzz|Packagist|Photon OS|Pub|PyPI|Red Hat|Rocky Linux|RubyGems|SUSE|SwiftURL|Ubuntu|Wolfi|GIT)(:.+)?$"
+ "pattern": "^(AlmaLinux|Alpaquita|Alpine|Android|BellSoft Hardened Containers|Bioconductor|Bitnami|Chainguard|ConanCenter|CRAN|crates\\.io|Debian|Drupal|GHC|GitHub Actions|Go|Hackage|Hex|Kubernetes|Linux|Mageia|Maven|MinimOS|npm|NuGet|openEuler|openSUSE|OSS-Fuzz|Packagist|Photon OS|Pub|PyPI|Red Hat|Rocky Linux|RubyGems|SUSE|SwiftURL|Ubuntu|Wolfi|GIT)(:.+)?$"
},
"prefix": {
"type": "string",
"title": "Currently supported home database identifier prefixes",
"description": "These home databases are also documented at https://ossf.github.io/osv-schema/#id-modified-fields",
- "pattern": "^(ASB-A|PUB-A|ALSA|ALBA|ALEA|BELL|BIT|CGA|CURL|CVE|DSA|DLA|ELA|DTSA|GHSA|GO|GSD|HSEC|KUBE|LBSEC|LSN|MAL|MINI|MGASA|OESA|OSV|openSUSE-SU|PHSA|PSF|PYSEC|RHBA|RHEA|RHSA|RLSA|RXSA|RSEC|RUSTSEC|SUSE-[SRFO]U|UBUNTU|USN|V8)-"
+ "pattern": "^(ASB-A|PUB-A|ALSA|ALBA|ALEA|BELL|BIT|CGA|CURL|CVE|DSA|DLA|DRUPAL|ELA|DTSA|GHSA|GO|GSD|HSEC|KUBE|LBSEC|LSN|MAL|MINI|MGASA|OESA|OSV|openSUSE-SU|PHSA|PSF|PYSEC|RHBA|RHEA|RHSA|RLSA|RXSA|RSEC|RUSTSEC|SUSE-[SRFO]U|UBUNTU|USN|V8)-"
},
"severity": {
"type": [