From d4648073211e8451d66e4c0399e9441250b60a76 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Mon, 3 Mar 2025 16:59:30 +0600 Subject: [PATCH] feat: add `--vuln-severity-source` flag (#8269) --- .../configuration/cli/trivy_filesystem.md | 1 + .../configuration/cli/trivy_image.md | 1 + .../configuration/cli/trivy_kubernetes.md | 1 + .../configuration/cli/trivy_repository.md | 1 + .../configuration/cli/trivy_rootfs.md | 1 + .../configuration/cli/trivy_sbom.md | 107 ++++++------ .../references/configuration/cli/trivy_vm.md | 1 + .../references/configuration/config-file.md | 4 + docs/docs/scanner/vulnerability.md | 24 +++ integration/client_server_test.go | 50 ++++-- integration/repo_test.go | 53 ++++-- .../testdata/npm-ubuntu-severity.json.golden | 160 ++++++++++++++++++ pkg/flag/options.go | 1 + pkg/flag/vulnerability_flags.go | 40 +++-- pkg/rpc/client/client.go | 13 +- pkg/rpc/server/server.go | 22 ++- pkg/rpc/server/server_test.go | 7 +- pkg/scanner/local/scan.go | 2 +- pkg/scanner/local/scan_test.go | 31 ++-- pkg/scanner/scan_test.go | 7 +- pkg/types/scan.go | 2 + pkg/vulnerability/vulnerability.go | 50 +++++- pkg/vulnerability/vulnerability_test.go | 97 ++++++++++- rpc/scanner/service.pb.go | 129 +++++++------- rpc/scanner/service.proto | 13 +- rpc/scanner/service.twirp.go | 90 +++++----- 26 files changed, 661 insertions(+), 247 deletions(-) create mode 100644 integration/testdata/npm-ubuntu-severity.json.golden diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md index 3ab174ccae..154b7ddea2 100644 --- a/docs/docs/references/configuration/cli/trivy_filesystem.md +++ b/docs/docs/references/configuration/cli/trivy_filesystem.md @@ -100,6 +100,7 @@ trivy filesystem [flags] PATH --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md index 556fd1c629..6cf60b5262 100644 --- a/docs/docs/references/configuration/cli/trivy_image.md +++ b/docs/docs/references/configuration/cli/trivy_image.md @@ -121,6 +121,7 @@ trivy image [flags] IMAGE_NAME --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md index 3f71510682..2a637d3076 100644 --- a/docs/docs/references/configuration/cli/trivy_kubernetes.md +++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md @@ -114,6 +114,7 @@ trivy kubernetes [flags] [CONTEXT] --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md index 41750ae8cb..98e54bb98c 100644 --- a/docs/docs/references/configuration/cli/trivy_repository.md +++ b/docs/docs/references/configuration/cli/trivy_repository.md @@ -99,6 +99,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL) --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md index c57074b96c..2ab6043da4 100644 --- a/docs/docs/references/configuration/cli/trivy_rootfs.md +++ b/docs/docs/references/configuration/cli/trivy_rootfs.md @@ -101,6 +101,7 @@ trivy rootfs [flags] ROOTDIR --trace enable more verbose trace output for custom queries --username strings username. Comma-separated usernames allowed. --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_sbom.md b/docs/docs/references/configuration/cli/trivy_sbom.md index 63f855b133..454f8f5d8c 100644 --- a/docs/docs/references/configuration/cli/trivy_sbom.md +++ b/docs/docs/references/configuration/cli/trivy_sbom.md @@ -20,59 +20,60 @@ trivy sbom [flags] SBOM_PATH ### Options ``` - --cache-backend string [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory") - --cache-ttl duration cache TTL when using redis as cache backend - --compliance string compliance report to generate - --custom-headers strings custom headers in client mode - --db-repository strings OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2]) - --detection-priority string specify the detection priority: - - "precise": Prioritizes precise by minimizing false positives. - - "comprehensive": Aims to detect more security findings at the cost of potential false positives. - (precise,comprehensive) (default "precise") - --distro string [EXPERIMENTAL] specify a distribution, / - --download-db-only download/update vulnerability database but don't run a scan - --download-java-db-only download/update Java index database but don't run a scan - --exit-code int specify exit code when any security issues are found - --exit-on-eol int exit with the specified code when the OS reaches end of service/life - --file-patterns strings specify config file patterns - -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") - -h, --help help for sbom - --ignore-policy string specify the Rego file path to evaluate each vulnerability - --ignore-status strings comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life) - --ignore-unfixed display only fixed vulnerabilities - --ignored-licenses strings specify a list of license to ignore - --ignorefile string specify .trivyignore file (default ".trivyignore") - --java-db-repository strings OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1]) - --list-all-pkgs output all packages in the JSON report regardless of vulnerability - --no-progress suppress progress bar - --offline-scan do not issue API requests to identify dependencies - -o, --output string output file name - --output-plugin-arg string [EXPERIMENTAL] output plugin arguments - --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. - --password-stdin password from stdin. Comma-separated passwords are not supported. - --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect]) - --pkg-types strings list of package types (os,library) (default [os,library]) - --redis-ca string redis ca file location, if using redis as cache backend - --redis-cert string redis certificate file location, if using redis as cache backend - --redis-key string redis key file location, if using redis as cache backend - --redis-tls enable redis TLS with public certificates, if using redis as cache backend - --registry-token string registry token - --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") - --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) - --scanners strings comma-separated list of what security issues to detect (vuln,license) (default [vuln]) - --server string server address in client mode - -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) - --show-suppressed [EXPERIMENTAL] show suppressed vulnerabilities - --skip-db-update skip updating vulnerability database - --skip-dirs strings specify the directories or glob patterns to skip - --skip-files strings specify the files or glob patterns to skip - --skip-java-db-update skip updating Java index database - --skip-vex-repo-update [EXPERIMENTAL] Skip VEX Repository update - -t, --template string output template - --token string for authentication in client/server mode - --token-header string specify a header name for token in client/server mode (default "Trivy-Token") - --username strings username. Comma-separated usernames allowed. - --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --cache-backend string [EXPERIMENTAL] cache backend (e.g. redis://localhost:6379) (default "memory") + --cache-ttl duration cache TTL when using redis as cache backend + --compliance string compliance report to generate + --custom-headers strings custom headers in client mode + --db-repository strings OCI repository(ies) to retrieve trivy-db in order of priority (default [mirror.gcr.io/aquasec/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2]) + --detection-priority string specify the detection priority: + - "precise": Prioritizes precise by minimizing false positives. + - "comprehensive": Aims to detect more security findings at the cost of potential false positives. + (precise,comprehensive) (default "precise") + --distro string [EXPERIMENTAL] specify a distribution, / + --download-db-only download/update vulnerability database but don't run a scan + --download-java-db-only download/update Java index database but don't run a scan + --exit-code int specify exit code when any security issues are found + --exit-on-eol int exit with the specified code when the OS reaches end of service/life + --file-patterns strings specify config file patterns + -f, --format string format (table,json,template,sarif,cyclonedx,spdx,spdx-json,github,cosign-vuln) (default "table") + -h, --help help for sbom + --ignore-policy string specify the Rego file path to evaluate each vulnerability + --ignore-status strings comma-separated list of vulnerability status to ignore (unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life) + --ignore-unfixed display only fixed vulnerabilities + --ignored-licenses strings specify a list of license to ignore + --ignorefile string specify .trivyignore file (default ".trivyignore") + --java-db-repository strings OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1]) + --list-all-pkgs output all packages in the JSON report regardless of vulnerability + --no-progress suppress progress bar + --offline-scan do not issue API requests to identify dependencies + -o, --output string output file name + --output-plugin-arg string [EXPERIMENTAL] output plugin arguments + --password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons. + --password-stdin password from stdin. Comma-separated passwords are not supported. + --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect]) + --pkg-types strings list of package types (os,library) (default [os,library]) + --redis-ca string redis ca file location, if using redis as cache backend + --redis-cert string redis certificate file location, if using redis as cache backend + --redis-key string redis key file location, if using redis as cache backend + --redis-tls enable redis TLS with public certificates, if using redis as cache backend + --registry-token string registry token + --rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev") + --sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor) + --scanners strings comma-separated list of what security issues to detect (vuln,license) (default [vuln]) + --server string server address in client mode + -s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL]) + --show-suppressed [EXPERIMENTAL] show suppressed vulnerabilities + --skip-db-update skip updating vulnerability database + --skip-dirs strings specify the directories or glob patterns to skip + --skip-files strings specify the files or glob patterns to skip + --skip-java-db-update skip updating Java index database + --skip-vex-repo-update [EXPERIMENTAL] Skip VEX Repository update + -t, --template string output template + --token string for authentication in client/server mode + --token-header string specify a header name for token in client/server mode (default "Trivy-Token") + --username strings username. Comma-separated usernames allowed. + --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md index 52d19114c9..2aef1a8864 100644 --- a/docs/docs/references/configuration/cli/trivy_vm.md +++ b/docs/docs/references/configuration/cli/trivy_vm.md @@ -86,6 +86,7 @@ trivy vm [flags] VM_IMAGE --token string for authentication in client/server mode --token-header string specify a header name for token in client/server mode (default "Trivy-Token") --vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) + --vuln-severity-source strings order of data sources for selecting vulnerability severity level (nvd,redhat,redhat-oval,debian,ubuntu,alpine,amazon,oracle-oval,suse-cvrf,photon,arch-linux,alma,rocky,cbl-mariner,azure,ruby-advisory-db,php-security-advisories,nodejs-security-wg,ghsa,glad,aqua,osv,k8s,wolfi,chainguard,bitnami,govulndb,auto) (default [auto]) ``` ### Options inherited from parent commands diff --git a/docs/docs/references/configuration/config-file.md b/docs/docs/references/configuration/config-file.md index b2678bf51f..b246a687da 100644 --- a/docs/docs/references/configuration/config-file.md +++ b/docs/docs/references/configuration/config-file.md @@ -626,6 +626,10 @@ vulnerability: # Same as '--ignore-unfixed' ignore-unfixed: false + # Same as '--vuln-severity-source' + severity-source: + - auto + # Same as '--skip-vex-repo-update' skip-vex-repo-update: false diff --git a/docs/docs/scanner/vulnerability.md b/docs/docs/scanner/vulnerability.md index 26aeacee58..0eb47aaaa8 100644 --- a/docs/docs/scanner/vulnerability.md +++ b/docs/docs/scanner/vulnerability.md @@ -345,6 +345,30 @@ However, in some cases, you may want to scan an image with a different OS versio Also, you may want to specify the OS version when OS is not detected. For these cases, Trivy supports a `--distro` flag using the `/` format (e.g. `alpine/3.20`) to set the desired OS version. +### Severity selection +By default, Trivy automatically detects severity (as described [here](#severity-selection)). +But there are cases when you may want to use your own source priority. Trivy supports the `--vuln-severity-source` flag for this. + +Fill in a list of required sources, and Trivy will check the sources in that order until it finds an existing severity. +If no source has the severity - Trivy will use the `UNKNOWN` severity. + +!!! note + To use the default logic in combination with your sources - use the `auto` value. + +Example logic for the following vendor severity levels when scanning an Alpine image: + +```json +"VendorSeverity": { + "ghsa": 3, + "nvd": 4, +} +``` + +- `--vuln-severity-source auto,nvd` - severity is `CRITICAL`, got from `auto`. +- `--vuln-severity-source alpine,auto` - severity is `CRITICAL`, got from `auto`. +- `--vuln-severity-source alpine,ghsa` - severity is `HIGH`, got from `ghsa`. +- `--vuln-severity-source alpine,alma` - severity is `UNKNOWN`. + [^1]: https://github.com/GoogleContainerTools/distroless [nvd-CVE-2023-0464]: https://nvd.nist.gov/vuln/detail/CVE-2023-0464 diff --git a/integration/client_server_test.go b/integration/client_server_test.go index 6a9dda6a59..7e80fd9f16 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -22,21 +22,22 @@ import ( ) type csArgs struct { - Command string - RemoteAddrOption string - Format types.Format - TemplatePath string - IgnoreUnfixed bool - Severity []string - IgnoreIDs []string - Input string - ClientToken string - ClientTokenHeader string - PathPrefix string - ListAllPackages bool - Target string - secretConfig string - Distro string + Command string + RemoteAddrOption string + Format types.Format + TemplatePath string + IgnoreUnfixed bool + Severity []string + IgnoreIDs []string + Input string + ClientToken string + ClientTokenHeader string + PathPrefix string + ListAllPackages bool + Target string + secretConfig string + Distro string + VulnSeveritySources []string } func TestClientServer(t *testing.T) { @@ -280,6 +281,19 @@ func TestClientServer(t *testing.T) { }, golden: "testdata/npm.json.golden", }, + { + name: "scan package-lock.json with severity from `ubuntu` in client/server mode", + args: csArgs{ + Command: "repo", + RemoteAddrOption: "--server", + Target: "testdata/fixtures/repo/npm/", + VulnSeveritySources: []string{ + "alpine", + "ubuntu", + }, + }, + golden: "testdata/npm-ubuntu-severity.json.golden", + }, { name: "scan sample.pem with repo command in client/server mode", args: csArgs{ @@ -677,6 +691,12 @@ func setupClient(t *testing.T, c csArgs, addr string, cacheDir string) []string ) } + if len(c.VulnSeveritySources) != 0 { + osArgs = append(osArgs, + "--vuln-severity-source", strings.Join(c.VulnSeveritySources, ","), + ) + } + if len(c.IgnoreIDs) != 0 { trivyIgnore := filepath.Join(t.TempDir(), ".trivyignore") err := os.WriteFile(trivyIgnore, []byte(strings.Join(c.IgnoreIDs, "\n")), 0444) diff --git a/integration/repo_test.go b/integration/repo_test.go index 365056a83f..bd19e09976 100644 --- a/integration/repo_test.go +++ b/integration/repo_test.go @@ -18,23 +18,24 @@ import ( func TestRepository(t *testing.T) { t.Setenv("NUGET_PACKAGES", t.TempDir()) type args struct { - scanner types.Scanner - ignoreIDs []string - policyPaths []string - namespaces []string - listAllPkgs bool - input string - secretConfig string - filePatterns []string - helmSet []string - helmValuesFile []string - skipFiles []string - skipDirs []string - command string - format types.Format - includeDevDeps bool - parallel int - vex string + scanner types.Scanner + ignoreIDs []string + policyPaths []string + namespaces []string + listAllPkgs bool + input string + secretConfig string + filePatterns []string + helmSet []string + helmValuesFile []string + skipFiles []string + skipDirs []string + command string + format types.Format + includeDevDeps bool + parallel int + vex string + vulnSeveritySources []string } tests := []struct { name string @@ -104,6 +105,18 @@ func TestRepository(t *testing.T) { }, golden: "testdata/npm.json.golden", }, + { + name: "npm with severity from ubuntu", + args: args{ + scanner: types.VulnerabilityScanner, + input: "testdata/fixtures/repo/npm", + vulnSeveritySources: []string{ + "alpine", + "ubuntu", + }, + }, + golden: "testdata/npm-ubuntu-severity.json.golden", + }, { name: "npm with dev deps", args: args{ @@ -538,6 +551,12 @@ func TestRepository(t *testing.T) { } } + if len(tt.args.vulnSeveritySources) != 0 { + osArgs = append(osArgs, + "--vuln-severity-source", strings.Join(tt.args.vulnSeveritySources, ","), + ) + } + if tt.args.listAllPkgs { osArgs = append(osArgs, "--list-all-pkgs") } diff --git a/integration/testdata/npm-ubuntu-severity.json.golden b/integration/testdata/npm-ubuntu-severity.json.golden new file mode 100644 index 0000000000..c96d4e8b2d --- /dev/null +++ b/integration/testdata/npm-ubuntu-severity.json.golden @@ -0,0 +1,160 @@ +{ + "SchemaVersion": 2, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", + "ArtifactName": "testdata/fixtures/repo/npm", + "ArtifactType": "repository", + "Metadata": { + "ImageConfig": { + "architecture": "", + "created": "0001-01-01T00:00:00Z", + "os": "", + "rootfs": { + "type": "", + "diff_ids": null + }, + "config": {} + } + }, + "Results": [ + { + "Target": "package-lock.json", + "Class": "lang-pkgs", + "Type": "npm", + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2019-11358", + "PkgID": "jquery@3.3.9", + "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.3.9", + "UID": "e19e84d31f72b60c" + }, + "InstalledVersion": "3.3.9", + "FixedVersion": "3.4.0", + "Status": "fixed", + "Layer": {}, + "SeveritySource": "ubuntu", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-11358", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory Npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Title": "jquery: Prototype pollution in object's prototype leading to denial of service, remote code execution, or property injection", + "Description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.", + "Severity": "LOW", + "CweIDs": [ + "CWE-79" + ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V2Score": 4.3, + "V3Score": 6.1 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", + "V3Score": 5.6 + } + }, + "References": [ + "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html", + "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00025.html", + "http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html", + "http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html", + "http://packetstormsecurity.com/files/156743/OctoberCMS-Insecure-Dependencies.html", + "http://seclists.org/fulldisclosure/2019/May/10", + "http://seclists.org/fulldisclosure/2019/May/11", + "http://seclists.org/fulldisclosure/2019/May/13", + "http://www.openwall.com/lists/oss-security/2019/06/03/2", + "http://www.securityfocus.com/bid/108023", + "https://access.redhat.com/errata/RHBA-2019:1570", + "https://access.redhat.com/errata/RHSA-2019:1456", + "https://access.redhat.com/errata/RHSA-2019:2587", + "https://access.redhat.com/errata/RHSA-2019:3023", + "https://access.redhat.com/errata/RHSA-2019:3024", + "https://access.redhat.com/security/cve/CVE-2019-11358", + "https://backdropcms.org/security/backdrop-sa-core-2019-009", + "https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358", + "https://github.com/DanielRuf/snyk-js-jquery-174006?files=1", + "https://github.com/advisories/GHSA-6c3j-c64m-qhgq", + "https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b", + "https://github.com/jquery/jquery/pull/4333", + "https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434", + "https://hackerone.com/reports/454365", + "https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44601", + "https://linux.oracle.com/cve/CVE-2019-11358.html", + "https://linux.oracle.com/errata/ELSA-2020-4847.html", + "https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/519eb0fd45642dcecd9ff74cb3e71c20a4753f7d82e2f07864b5108f@%3Cdev.drill.apache.org%3E", + "https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/b0656d359c7d40ec9f39c8cc61bca66802ef9a2a12ee199f5b0c1442@%3Cdev.drill.apache.org%3E", + "https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/ba79cf1658741e9f146e4c59b50aee56656ea95d841d358d006c18b6@%3Ccommits.roller.apache.org%3E", + "https://lists.apache.org/thread.html/bcce5a9c532b386c68dab2f6b3ce8b0cc9b950ec551766e76391caa3@%3Ccommits.nifi.apache.org%3E", + "https://lists.apache.org/thread.html/f9bc3e55f4e28d1dcd1a69aae6d53e609a758e34d2869b4d798e13cc@%3Cissues.drill.apache.org%3E", + "https://lists.apache.org/thread.html/r2041a75d3fc09dec55adfd95d598b38d22715303f65c997c054844c9@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r2baacab6e0acb5a2092eb46ae04fd6c3e8277b4fd79b1ffb7f3254fa@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r38f0d1aa3c923c22977fe7376508f030f22e22c1379fbb155bf29766@%3Cdev.syncope.apache.org%3E", + "https://lists.apache.org/thread.html/r41b5bfe009c845f67d4f68948cc9419ac2d62e287804aafd72892b08@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r7aac081cbddb6baa24b75e74abf0929bf309b176755a53e3ed810355@%3Cdev.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r7d64895cc4dff84d0becfc572b20c0e4bf9bfa7b10c6f5f73e783734@%3Cdev.storm.apache.org%3E", + "https://lists.apache.org/thread.html/r7e8ebccb7c022e41295f6fdb7b971209b83702339f872ddd8cf8bf73@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/rac25da84ecdcd36f6de5ad0d255f4e967209bbbebddb285e231da37d@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/rca37935d661f4689cb4119f1b3b224413b22be161b678e6e6ce0c69b@%3Ccommits.nifi.apache.org%3E", + "https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html", + "https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html", + "https://lists.debian.org/debian-lts-announce/2020/02/msg00024.html", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/", + "https://nvd.nist.gov/vuln/detail/CVE-2019-11358", + "https://seclists.org/bugtraq/2019/Apr/32", + "https://seclists.org/bugtraq/2019/Jun/12", + "https://seclists.org/bugtraq/2019/May/18", + "https://security.netapp.com/advisory/ntap-20190919-0001/", + "https://snyk.io/vuln/SNYK-JS-JQUERY-174006", + "https://www.debian.org/security/2019/dsa-4434", + "https://www.debian.org/security/2019/dsa-4460", + "https://www.drupal.org/sa-core-2019-006", + "https://www.oracle.com//security-alerts/cpujul2021.html", + "https://www.oracle.com/security-alerts/cpuApr2021.html", + "https://www.oracle.com/security-alerts/cpuapr2020.html", + "https://www.oracle.com/security-alerts/cpujan2020.html", + "https://www.oracle.com/security-alerts/cpujan2021.html", + "https://www.oracle.com/security-alerts/cpujul2020.html", + "https://www.oracle.com/security-alerts/cpuoct2020.html", + "https://www.oracle.com/security-alerts/cpuoct2021.html", + "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html", + "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html", + "https://www.privacy-wise.com/mitigating-cve-2019-11358-in-old-versions-of-jquery/", + "https://www.synology.com/security/advisory/Synology_SA_19_19", + "https://www.tenable.com/security/tns-2019-08", + "https://www.tenable.com/security/tns-2020-02" + ], + "PublishedDate": "2019-04-20T00:29:00Z", + "LastModifiedDate": "2021-10-20T11:15:00Z" + } + ] + } + ] +} diff --git a/pkg/flag/options.go b/pkg/flag/options.go index 775eec1366..0b7772a091 100644 --- a/pkg/flag/options.go +++ b/pkg/flag/options.go @@ -463,6 +463,7 @@ func (o *Options) ScanOpts() types.ScanOptions { FilePatterns: o.FilePatterns, IncludeDevDeps: o.IncludeDevDeps, Distro: o.Distro, + VulnSeveritySources: o.VulnSeveritySources, } } diff --git a/pkg/flag/vulnerability_flags.go b/pkg/flag/vulnerability_flags.go index 2e9d651b63..0ce06a4ced 100644 --- a/pkg/flag/vulnerability_flags.go +++ b/pkg/flag/vulnerability_flags.go @@ -4,8 +4,10 @@ import ( "github.com/samber/lo" dbTypes "github.com/aquasecurity/trivy-db/pkg/types" + "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/vex" + xstrings "github.com/aquasecurity/trivy/pkg/x/strings" ) var ( @@ -30,27 +32,39 @@ var ( ConfigName: "vulnerability.skip-vex-repo-update", Usage: `[EXPERIMENTAL] Skip VEX Repository update`, } + VulnSeveritySourceFlag = Flag[[]string]{ + Name: "vuln-severity-source", + ConfigName: "vulnerability.severity-source", + Default: []string{ + "auto", + }, + Values: append(xstrings.ToStringSlice(vulnerability.AllSourceIDs), "auto"), + Usage: "order of data sources for selecting vulnerability severity level", + } ) type VulnerabilityFlagGroup struct { - IgnoreUnfixed *Flag[bool] - IgnoreStatus *Flag[[]string] - VEX *Flag[[]string] - SkipVEXRepoUpdate *Flag[bool] + IgnoreUnfixed *Flag[bool] + IgnoreStatus *Flag[[]string] + VEX *Flag[[]string] + SkipVEXRepoUpdate *Flag[bool] + VulnSeveritySource *Flag[[]string] } type VulnerabilityOptions struct { - IgnoreStatuses []dbTypes.Status - VEXSources []vex.Source - SkipVEXRepoUpdate bool + IgnoreStatuses []dbTypes.Status + VEXSources []vex.Source + SkipVEXRepoUpdate bool + VulnSeveritySources []dbTypes.SourceID } func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup { return &VulnerabilityFlagGroup{ - IgnoreUnfixed: IgnoreUnfixedFlag.Clone(), - IgnoreStatus: IgnoreStatusFlag.Clone(), - VEX: VEXFlag.Clone(), - SkipVEXRepoUpdate: SkipVEXRepoUpdateFlag.Clone(), + IgnoreUnfixed: IgnoreUnfixedFlag.Clone(), + IgnoreStatus: IgnoreStatusFlag.Clone(), + VEX: VEXFlag.Clone(), + SkipVEXRepoUpdate: SkipVEXRepoUpdateFlag.Clone(), + VulnSeveritySource: VulnSeveritySourceFlag.Clone(), } } @@ -64,6 +78,7 @@ func (f *VulnerabilityFlagGroup) Flags() []Flagger { f.IgnoreStatus, f.VEX, f.SkipVEXRepoUpdate, + f.VulnSeveritySource, } } @@ -100,6 +115,7 @@ func (f *VulnerabilityFlagGroup) ToOptions() (VulnerabilityOptions, error) { VEXSources: lo.Map(f.VEX.Value(), func(s string, _ int) vex.Source { return vex.NewSource(s) }), - SkipVEXRepoUpdate: f.SkipVEXRepoUpdate.Value(), + SkipVEXRepoUpdate: f.SkipVEXRepoUpdate.Value(), + VulnSeveritySources: xstrings.ToTSlice[dbTypes.SourceID](f.VulnSeveritySource.Value()), }, nil } diff --git a/pkg/rpc/client/client.go b/pkg/rpc/client/client.go index dd13b14587..328d880e07 100644 --- a/pkg/rpc/client/client.go +++ b/pkg/rpc/client/client.go @@ -93,12 +93,13 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys ArtifactId: artifactKey, BlobIds: blobKeys, Options: &rpc.ScanOptions{ - PkgTypes: opts.PkgTypes, - PkgRelationships: xstrings.ToStringSlice(opts.PkgRelationships), - Scanners: xstrings.ToStringSlice(opts.Scanners), - LicenseCategories: licenseCategories, - IncludeDevDeps: opts.IncludeDevDeps, - Distro: distro, + PkgTypes: opts.PkgTypes, + PkgRelationships: xstrings.ToStringSlice(opts.PkgRelationships), + Scanners: xstrings.ToStringSlice(opts.Scanners), + LicenseCategories: licenseCategories, + IncludeDevDeps: opts.IncludeDevDeps, + Distro: distro, + VulnSeveritySources: xstrings.ToStringSlice(opts.VulnSeveritySources), }, }) return err diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 0bc7492783..39d5a76154 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -8,6 +8,7 @@ import ( "golang.org/x/xerrors" "google.golang.org/protobuf/types/known/emptypb" + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy/pkg/cache" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" @@ -15,6 +16,7 @@ import ( "github.com/aquasecurity/trivy/pkg/scanner" "github.com/aquasecurity/trivy/pkg/scanner/local" "github.com/aquasecurity/trivy/pkg/types" + xstrings "github.com/aquasecurity/trivy/pkg/x/strings" rpcCache "github.com/aquasecurity/trivy/rpc/cache" rpcScanner "github.com/aquasecurity/trivy/rpc/scanner" ) @@ -81,13 +83,21 @@ func (s *ScanServer) ToOptions(in *rpcScanner.ScanOptions) types.ScanOptions { distro.Name = in.Distro.Name } + vulnSeveritySources := xstrings.ToTSlice[dbTypes.SourceID](in.VulnSeveritySources) + if len(vulnSeveritySources) == 0 { + vulnSeveritySources = []dbTypes.SourceID{ + "auto", // For backward compatibility + } + } + return types.ScanOptions{ - PkgTypes: in.PkgTypes, - PkgRelationships: pkgRelationships, - Scanners: scanners, - IncludeDevDeps: in.IncludeDevDeps, - LicenseCategories: licenseCategories, - Distro: distro, + PkgTypes: in.PkgTypes, + PkgRelationships: pkgRelationships, + Scanners: scanners, + IncludeDevDeps: in.IncludeDevDeps, + LicenseCategories: licenseCategories, + Distro: distro, + VulnSeveritySources: vulnSeveritySources, } } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index e6a6dde6a2..7b25fbf68a 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -46,9 +46,10 @@ func TestScanServer_Scan(t *testing.T) { ArtifactId: "sha256:e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a", BlobIds: []string{"sha256:beee9f30bc1f711043e78d4a2be0668955d4b761d587d6f60c2c8dc081efb203"}, Options: &rpcScanner.ScanOptions{ - PkgTypes: []string{types.PkgTypeOS}, - Scanners: []string{string(types.VulnerabilityScanner)}, - PkgRelationships: []string{ftypes.RelationshipUnknown.String()}, + PkgTypes: []string{types.PkgTypeOS}, + Scanners: []string{string(types.VulnerabilityScanner)}, + PkgRelationships: []string{ftypes.RelationshipUnknown.String()}, + VulnSeveritySources: []string{"auto"}, }, }, }, diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index a9afeb169c..124587487d 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -145,7 +145,7 @@ func (s Scanner) ScanTarget(ctx context.Context, target types.ScanTarget, option for i := range results { // Fill vulnerability details - s.vulnClient.FillInfo(results[i].Vulnerabilities) + s.vulnClient.FillInfo(results[i].Vulnerabilities, options.VulnSeveritySources) } // Post scanning diff --git a/pkg/scanner/local/scan_test.go b/pkg/scanner/local/scan_test.go index ce337f9d1f..34cdbf00c7 100644 --- a/pkg/scanner/local/scan_test.go +++ b/pkg/scanner/local/scan_test.go @@ -167,8 +167,9 @@ func TestScanner_Scan(t *testing.T) { types.PkgTypeOS, types.PkgTypeLibrary, }, - PkgRelationships: ftypes.Relationships, - Scanners: types.Scanners{types.VulnerabilityScanner}, + PkgRelationships: ftypes.Relationships, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -279,6 +280,7 @@ func TestScanner_Scan(t *testing.T) { Family: "alpine", Name: "3.11", }, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -454,8 +456,9 @@ func TestScanner_Scan(t *testing.T) { types.PkgTypeOS, types.PkgTypeLibrary, }, - PkgRelationships: ftypes.Relationships, - Scanners: types.Scanners{types.VulnerabilityScanner}, + PkgRelationships: ftypes.Relationships, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -532,9 +535,10 @@ func TestScanner_Scan(t *testing.T) { target: "./result.cdx", layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, options: types.ScanOptions{ - PkgTypes: []string{types.PkgTypeLibrary}, - PkgRelationships: ftypes.Relationships, - Scanners: types.Scanners{types.VulnerabilityScanner}, + PkgTypes: []string{types.PkgTypeLibrary}, + PkgRelationships: ftypes.Relationships, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -642,8 +646,9 @@ func TestScanner_Scan(t *testing.T) { types.PkgTypeOS, types.PkgTypeLibrary, }, - PkgRelationships: ftypes.Relationships, - Scanners: types.Scanners{types.VulnerabilityScanner}, + PkgRelationships: ftypes.Relationships, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -722,8 +727,9 @@ func TestScanner_Scan(t *testing.T) { types.PkgTypeOS, types.PkgTypeLibrary, }, - PkgRelationships: ftypes.Relationships, - Scanners: types.Scanners{types.VulnerabilityScanner}, + PkgRelationships: ftypes.Relationships, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -821,7 +827,8 @@ func TestScanner_Scan(t *testing.T) { ftypes.RelationshipRoot, ftypes.RelationshipIndirect, }, - Scanners: types.Scanners{types.VulnerabilityScanner}, + Scanners: types.Scanners{types.VulnerabilityScanner}, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, diff --git a/pkg/scanner/scan_test.go b/pkg/scanner/scan_test.go index a5a8df7f65..949baed503 100644 --- a/pkg/scanner/scan_test.go +++ b/pkg/scanner/scan_test.go @@ -43,9 +43,10 @@ func TestScanner_ScanArtifact(t *testing.T) { name: "happy path", args: args{ options: tTypes.ScanOptions{ - PkgTypes: []string{"os"}, - Scanners: tTypes.Scanners{tTypes.VulnerabilityScanner}, - PkgRelationships: ftypes.Relationships, + PkgTypes: []string{"os"}, + Scanners: tTypes.Scanners{tTypes.VulnerabilityScanner}, + PkgRelationships: ftypes.Relationships, + VulnSeveritySources: []dbTypes.SourceID{"auto"}, }, }, imagePath: "../fanal/test/testdata/alpine-311.tar.gz", diff --git a/pkg/types/scan.go b/pkg/types/scan.go index 4dedbce6fc..1d1586082b 100644 --- a/pkg/types/scan.go +++ b/pkg/types/scan.go @@ -3,6 +3,7 @@ package types import ( "slices" + dbTypes "github.com/aquasecurity/trivy-db/pkg/types" "github.com/aquasecurity/trivy/pkg/fanal/types" ) @@ -122,4 +123,5 @@ type ScanOptions struct { FilePatterns []string IncludeDevDeps bool Distro types.OS // Forced OS + VulnSeveritySources []dbTypes.SourceID } diff --git a/pkg/vulnerability/vulnerability.go b/pkg/vulnerability/vulnerability.go index 501a701a85..971da8ca0c 100644 --- a/pkg/vulnerability/vulnerability.go +++ b/pkg/vulnerability/vulnerability.go @@ -1,6 +1,7 @@ package vulnerability import ( + "slices" "strings" "sync" @@ -67,7 +68,8 @@ func NewClient(dbc db.Operation) Client { } // FillInfo fills extra info in vulnerability objects -func (c Client) FillInfo(vulns []types.DetectedVulnerability) { +func (c Client) FillInfo(vulns []types.DetectedVulnerability, severitySources []dbTypes.SourceID) { + var noSeverityIDs []string for i := range vulns { // Add the vulnerability status // Some vendors such as Red Hat have their own vulnerability status, and we use it. @@ -90,7 +92,10 @@ func (c Client) FillInfo(vulns []types.DetectedVulnerability) { dataSource := lo.FromPtr(vulns[i].DataSource) // Select the severity according to the detected sourceID. - severity, severitySource := c.getVendorSeverity(vulnID, &vuln, dataSource) + severity, severitySource := c.getSeverity(vulnID, &vuln, dataSource, severitySources) + if severity == dbTypes.SeverityUnknown.String() { + noSeverityIDs = append(noSeverityIDs, vulnID) + } // The vendor might provide package-specific severity like Debian. // For example, CVE-2015-2328 in Debian has "unimportant" for mongodb and "low" for pcre3. @@ -114,23 +119,50 @@ func (c Client) FillInfo(vulns []types.DetectedVulnerability) { vulns[i].SeveritySource = severitySource vulns[i].PrimaryURL = c.getPrimaryURL(vulnID, vuln.References, dataSource.ID) } + + if !slices.Contains(severitySources, "auto") && len(noSeverityIDs) > 0 { + log.Warn("No severity found in specified sources", + log.Any("vulnerability-ids", noSeverityIDs), log.Any("severity-sources", severitySources)) + } } -func (c Client) getVendorSeverity(vulnID string, vuln *dbTypes.Vulnerability, dataSource dbTypes.DataSource) (string, dbTypes.SourceID) { +func (c Client) getSeverity(vulnID string, vuln *dbTypes.Vulnerability, dataSource dbTypes.DataSource, severitySources []dbTypes.SourceID) (string, dbTypes.SourceID) { + for _, source := range severitySources { + if source == "auto" { + return c.autoDetectSeverity(vulnID, vuln, dataSource) + } + + if severity, ok := vuln.VendorSeverity[source]; ok { + return severity.String(), source + } + } + + return dbTypes.SeverityUnknown.String(), "" +} + +// autoDetectSeverity detects the severity from the vulnerability ID and data source. +// +// The severity is determined in the following order: +// 1. If the vulnerability is from a specific data source (e.g., Red Hat advisories for Red Hat distributions), +// use the severity from that data source. +// 2. For GHSA-IDs, also consider the severity from GitHub Advisory Database. +// 3. Use the severity from NVD as a fallback. +// 4. Try severities from other data sources (e.g., Debian severity for Red Hat distributions). +// 5. If no severity is found from any data source, return "UNKNOWN". +func (c Client) autoDetectSeverity(vulnID string, vuln *dbTypes.Vulnerability, dataSource dbTypes.DataSource) (string, dbTypes.SourceID) { + autoSeveritySrcs := []dbTypes.SourceID{dataSource.ID, vulnerability.NVD} if vs, ok := vuln.VendorSeverity[dataSource.ID]; ok { return vs.String(), dataSource.ID } // use severity from GitHub for all GHSA-xxx vulnerabilities if strings.HasPrefix(vulnID, "GHSA-") { - if vs, ok := vuln.VendorSeverity[vulnerability.GHSA]; ok { - return vs.String(), vulnerability.GHSA - } + // use severity from GitHub for all GHSA-IDs + autoSeveritySrcs = []dbTypes.SourceID{dataSource.ID, vulnerability.GHSA, vulnerability.NVD} } - // Try NVD as a fallback if it exists - if vs, ok := vuln.VendorSeverity[vulnerability.NVD]; ok { - return vs.String(), vulnerability.NVD + if severity, severitySource := c.getSeverity(vulnID, vuln, dataSource, autoSeveritySrcs); severity != dbTypes.SeverityUnknown.String() { + return severity, severitySource } if vuln.Severity == "" { diff --git a/pkg/vulnerability/vulnerability_test.go b/pkg/vulnerability/vulnerability_test.go index d377ef6e47..1c86200628 100644 --- a/pkg/vulnerability/vulnerability_test.go +++ b/pkg/vulnerability/vulnerability_test.go @@ -17,6 +17,7 @@ import ( func TestClient_FillInfo(t *testing.T) { tests := []struct { name string + vulnSeveritySources []dbTypes.SourceID fixtures []string vulns []types.DetectedVulnerability expectedVulnerabilities []types.DetectedVulnerability @@ -282,6 +283,94 @@ func TestClient_FillInfo(t *testing.T) { }, }, }, + { + name: "happy path. Severity got from 'nvd' from VulnSeveritySources", + vulnSeveritySources: []dbTypes.SourceID{ + "alma", + "alpine", + "nvd", + }, + fixtures: []string{"testdata/fixtures/vulnerability.yaml"}, + vulns: []types.DetectedVulnerability{ + {VulnerabilityID: "CVE-2022-0001"}, + }, + expectedVulnerabilities: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2022-0001", + Status: dbTypes.StatusAffected, + SeveritySource: vulnerability.NVD, + Vulnerability: dbTypes.Vulnerability{ + Title: "dos", + Description: "dos vulnerability", + Severity: dbTypes.SeverityLow.String(), + References: []string{"http://example.com"}, + VendorSeverity: map[dbTypes.SourceID]dbTypes.Severity{ + "nvd": dbTypes.SeverityLow, + "ghsa": dbTypes.SeverityHigh, + }, + }, + PrimaryURL: "https://avd.aquasec.com/nvd/cve-2022-0001", + }, + }, + }, + { + name: "happy path. Severity got from 'auto' from VulnSeveritySources", + vulnSeveritySources: []dbTypes.SourceID{ + "alma", + "alpine", + "auto", + }, + fixtures: []string{"testdata/fixtures/vulnerability.yaml"}, + vulns: []types.DetectedVulnerability{ + {VulnerabilityID: "CVE-2022-0001"}, + }, + expectedVulnerabilities: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2022-0001", + Status: dbTypes.StatusAffected, + SeveritySource: vulnerability.NVD, + Vulnerability: dbTypes.Vulnerability{ + Title: "dos", + Description: "dos vulnerability", + Severity: dbTypes.SeverityLow.String(), + References: []string{"http://example.com"}, + VendorSeverity: map[dbTypes.SourceID]dbTypes.Severity{ + "nvd": dbTypes.SeverityLow, + "ghsa": dbTypes.SeverityHigh, + }, + }, + PrimaryURL: "https://avd.aquasec.com/nvd/cve-2022-0001", + }, + }, + }, + { + name: "happy path. Severity didn't find from VulnSeveritySources", + vulnSeveritySources: []dbTypes.SourceID{ + "alma", + "alpine", + }, + fixtures: []string{"testdata/fixtures/vulnerability.yaml"}, + vulns: []types.DetectedVulnerability{ + {VulnerabilityID: "CVE-2022-0001"}, + }, + expectedVulnerabilities: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2022-0001", + Status: dbTypes.StatusAffected, + Vulnerability: dbTypes.Vulnerability{ + Title: "dos", + Description: "dos vulnerability", + Severity: dbTypes.SeverityUnknown.String(), + References: []string{"http://example.com"}, + VendorSeverity: map[dbTypes.SourceID]dbTypes.Severity{ + "nvd": dbTypes.SeverityLow, + "ghsa": dbTypes.SeverityHigh, + }, + }, + PrimaryURL: "https://avd.aquasec.com/nvd/cve-2022-0001", + }, + }, + }, { name: "GetVulnerability returns an error", fixtures: []string{"testdata/fixtures/sad.yaml"}, @@ -306,7 +395,13 @@ func TestClient_FillInfo(t *testing.T) { defer db.Close() c := vuln.NewClient(db.Config{}) - c.FillInfo(tt.vulns) + vulnSeveritySources := []dbTypes.SourceID{ + "auto", + } + if len(tt.vulnSeveritySources) > 0 { + vulnSeveritySources = tt.vulnSeveritySources + } + c.FillInfo(tt.vulns, vulnSeveritySources) assert.Equal(t, tt.expectedVulnerabilities, tt.vulns, tt.name) }) } diff --git a/rpc/scanner/service.pb.go b/rpc/scanner/service.pb.go index 00ff348524..3927282ad8 100644 --- a/rpc/scanner/service.pb.go +++ b/rpc/scanner/service.pb.go @@ -146,12 +146,13 @@ type ScanOptions struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - PkgTypes []string `protobuf:"bytes,1,rep,name=pkg_types,json=pkgTypes,proto3" json:"pkg_types,omitempty"` - Scanners []string `protobuf:"bytes,2,rep,name=scanners,proto3" json:"scanners,omitempty"` - LicenseCategories map[string]*Licenses `protobuf:"bytes,4,rep,name=license_categories,json=licenseCategories,proto3" json:"license_categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - IncludeDevDeps bool `protobuf:"varint,5,opt,name=include_dev_deps,json=includeDevDeps,proto3" json:"include_dev_deps,omitempty"` - PkgRelationships []string `protobuf:"bytes,6,rep,name=pkg_relationships,json=pkgRelationships,proto3" json:"pkg_relationships,omitempty"` - Distro *common.OS `protobuf:"bytes,7,opt,name=distro,proto3" json:"distro,omitempty"` + PkgTypes []string `protobuf:"bytes,1,rep,name=pkg_types,json=pkgTypes,proto3" json:"pkg_types,omitempty"` + Scanners []string `protobuf:"bytes,2,rep,name=scanners,proto3" json:"scanners,omitempty"` + LicenseCategories map[string]*Licenses `protobuf:"bytes,4,rep,name=license_categories,json=licenseCategories,proto3" json:"license_categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + IncludeDevDeps bool `protobuf:"varint,5,opt,name=include_dev_deps,json=includeDevDeps,proto3" json:"include_dev_deps,omitempty"` + PkgRelationships []string `protobuf:"bytes,6,rep,name=pkg_relationships,json=pkgRelationships,proto3" json:"pkg_relationships,omitempty"` + Distro *common.OS `protobuf:"bytes,7,opt,name=distro,proto3" json:"distro,omitempty"` + VulnSeveritySources []string `protobuf:"bytes,8,rep,name=vuln_severity_sources,json=vulnSeveritySources,proto3" json:"vuln_severity_sources,omitempty"` } func (x *ScanOptions) Reset() { @@ -228,6 +229,13 @@ func (x *ScanOptions) GetDistro() *common.OS { return nil } +func (x *ScanOptions) GetVulnSeveritySources() []string { + if x != nil { + return x.VulnSeveritySources + } + return nil +} + type ScanResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -414,7 +422,7 @@ var file_rpc_scanner_service_proto_rawDesc = []byte{ 0x53, 0x63, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x20, 0x0a, 0x08, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x94, 0x03, 0x0a, 0x0b, 0x53, 0x63, 0x61, 0x6e, 0x4f, + 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xc8, 0x03, 0x0a, 0x0b, 0x53, 0x63, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6b, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6b, 0x67, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18, @@ -433,58 +441,61 @@ var file_rpc_scanner_service_proto_rawDesc = []byte{ 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x68, 0x69, 0x70, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x64, 0x69, 0x73, 0x74, 0x72, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4f, 0x53, 0x52, 0x06, 0x64, - 0x69, 0x73, 0x74, 0x72, 0x6f, 0x1a, 0x60, 0x0a, 0x16, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x64, 0x0a, - 0x0c, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, - 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x72, 0x69, 0x76, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4f, 0x53, 0x52, 0x02, 0x6f, 0x73, 0x12, - 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x22, 0xd5, 0x03, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, - 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, - 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0f, 0x76, 0x75, - 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x54, 0x0a, - 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, - 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, - 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, - 0x12, 0x47, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, - 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, - 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, - 0x12, 0x39, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, - 0x65, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x32, 0x50, 0x0a, 0x07, 0x53, - 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x1d, - 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, - 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x71, 0x75, 0x61, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2f, 0x72, - 0x70, 0x63, 0x2f, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x73, 0x63, 0x61, 0x6e, 0x6e, - 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x73, 0x74, 0x72, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x73, 0x65, + 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x76, 0x75, 0x6c, 0x6e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, + 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x60, 0x0a, 0x16, 0x4c, 0x69, 0x63, + 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10, + 0x04, 0x22, 0x64, 0x0a, 0x0c, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x20, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4f, 0x53, 0x52, + 0x02, 0x6f, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xd5, 0x03, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x76, 0x75, + 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x12, 0x54, 0x0a, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, + 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0f, 0x63, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, + 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, + 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x32, + 0x50, 0x0a, 0x07, 0x53, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x63, + 0x61, 0x6e, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x71, 0x75, 0x61, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, + 0x76, 0x79, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x73, + 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/rpc/scanner/service.proto b/rpc/scanner/service.proto index d809d36610..3602875473 100644 --- a/rpc/scanner/service.proto +++ b/rpc/scanner/service.proto @@ -23,12 +23,13 @@ message Licenses { } message ScanOptions { - repeated string pkg_types = 1; - repeated string scanners = 2; - map license_categories = 4; - bool include_dev_deps = 5; - repeated string pkg_relationships = 6; - common.OS distro = 7; + repeated string pkg_types = 1; + repeated string scanners = 2; + map license_categories = 4; + bool include_dev_deps = 5; + repeated string pkg_relationships = 6; + common.OS distro = 7; + repeated string vuln_severity_sources = 8; reserved 3; // deleted 'list_all_packages' } diff --git a/rpc/scanner/service.twirp.go b/rpc/scanner/service.twirp.go index d7525d23c4..d763d6a080 100644 --- a/rpc/scanner/service.twirp.go +++ b/rpc/scanner/service.twirp.go @@ -1094,48 +1094,50 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) } var twirpFileDescriptor0 = []byte{ - // 685 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0x51, 0x6f, 0x1a, 0x47, - 0x10, 0x16, 0x1c, 0x86, 0x63, 0xa8, 0x6a, 0xbc, 0x6a, 0xad, 0x35, 0xae, 0x5b, 0xc4, 0x43, 0x85, - 0x54, 0x09, 0x6a, 0xdc, 0xaa, 0x4d, 0xf2, 0x16, 0xdb, 0x89, 0x1c, 0x25, 0xb2, 0xb5, 0x58, 0x79, - 0xc8, 0x0b, 0x59, 0xf6, 0xc6, 0xe7, 0x15, 0xc7, 0xed, 0x79, 0x77, 0x0f, 0x89, 0xff, 0x91, 0xa7, - 0xfc, 0xaf, 0xfc, 0x9f, 0x68, 0xf7, 0x0e, 0x64, 0x30, 0xce, 0x13, 0x3b, 0x33, 0xdf, 0xcc, 0x7c, - 0xcc, 0x7c, 0x37, 0x70, 0xa4, 0x33, 0x31, 0x34, 0x82, 0xa7, 0x29, 0xea, 0xa1, 0x41, 0xbd, 0x90, - 0x02, 0x07, 0x99, 0x56, 0x56, 0x91, 0xb6, 0xd5, 0x72, 0xb1, 0x1c, 0x94, 0xc1, 0xc1, 0xe2, 0xb4, - 0x43, 0x1d, 0x58, 0xa8, 0xf9, 0x5c, 0xa5, 0x9b, 0xd8, 0xde, 0xd7, 0x0a, 0xb4, 0xc6, 0x82, 0xa7, - 0x0c, 0x1f, 0x72, 0x34, 0x96, 0x1c, 0x42, 0xdd, 0x72, 0x1d, 0xa3, 0xa5, 0x95, 0x6e, 0xa5, 0xdf, - 0x64, 0xa5, 0x45, 0xfe, 0x80, 0x16, 0xd7, 0x56, 0xde, 0x71, 0x61, 0x27, 0x32, 0xa2, 0x55, 0x1f, - 0x84, 0x95, 0xeb, 0x2a, 0x22, 0x47, 0x10, 0x4e, 0x13, 0x35, 0x9d, 0xc8, 0xc8, 0xd0, 0xa0, 0x1b, - 0xf4, 0x9b, 0xac, 0xe1, 0xec, 0xab, 0xc8, 0x90, 0xff, 0xa0, 0xa1, 0x32, 0x2b, 0x55, 0x6a, 0x68, - 0xad, 0x5b, 0xe9, 0xb7, 0x46, 0x27, 0x83, 0x6d, 0x86, 0x03, 0xc7, 0xe1, 0xba, 0x00, 0xb1, 0x15, - 0xba, 0xd7, 0x85, 0xf0, 0xbd, 0x14, 0x98, 0x1a, 0x34, 0xe4, 0x17, 0xd8, 0x4b, 0xf9, 0x1c, 0x0d, - 0xad, 0xf8, 0xe2, 0x85, 0xd1, 0xfb, 0x12, 0x14, 0xf4, 0xcb, 0x54, 0x72, 0x0c, 0xcd, 0x6c, 0x16, - 0x4f, 0xec, 0x32, 0x5b, 0x23, 0xc3, 0x6c, 0x16, 0xdf, 0x3a, 0x9b, 0x74, 0x20, 0x2c, 0x3b, 0x1a, - 0x5a, 0x2d, 0x62, 0x2b, 0x9b, 0x08, 0x20, 0x49, 0xd1, 0x6a, 0x22, 0xb8, 0xc5, 0x58, 0x69, 0x89, - 0x8e, 0x6e, 0xd0, 0x6f, 0x8d, 0xfe, 0xf9, 0x21, 0xdd, 0x41, 0x49, 0xf1, 0x7c, 0x9d, 0x76, 0x99, - 0x5a, 0xbd, 0x64, 0x07, 0xc9, 0xb6, 0x9f, 0xf4, 0xa1, 0x2d, 0x53, 0x91, 0xe4, 0x11, 0x4e, 0x22, - 0x5c, 0x4c, 0x22, 0xcc, 0x0c, 0xdd, 0xeb, 0x56, 0xfa, 0x21, 0xfb, 0xb9, 0xf4, 0x5f, 0xe0, 0xe2, - 0x02, 0x33, 0x43, 0xfe, 0x82, 0x03, 0xf7, 0x3f, 0x34, 0x26, 0xdc, 0x37, 0xb9, 0x97, 0x99, 0xa1, - 0x75, 0xcf, 0xb9, 0x9d, 0xcd, 0x62, 0xf6, 0xd8, 0x4f, 0xfa, 0x50, 0x8f, 0xa4, 0xb1, 0x5a, 0xd1, - 0x86, 0x1f, 0x6f, 0xbb, 0xe4, 0x5b, 0x2c, 0x7c, 0x70, 0x3d, 0x66, 0x65, 0xbc, 0xf3, 0x19, 0x0e, - 0x77, 0xb3, 0x25, 0x6d, 0x08, 0x66, 0xb8, 0x2c, 0x97, 0xee, 0x9e, 0xe4, 0x6f, 0xd8, 0x5b, 0xf0, - 0x24, 0x47, 0xbf, 0xeb, 0xd6, 0xa8, 0xf3, 0x74, 0x08, 0xab, 0xdd, 0xb0, 0x02, 0xf8, 0xb2, 0xfa, - 0x7f, 0xe5, 0x5d, 0x2d, 0x0c, 0xda, 0xb5, 0x5e, 0x04, 0x3f, 0x15, 0xa2, 0x32, 0x99, 0x4a, 0x0d, - 0x92, 0x2e, 0x54, 0x95, 0xf1, 0xc5, 0x77, 0xb1, 0xab, 0x2a, 0x43, 0x46, 0xd0, 0xd0, 0x68, 0xf2, - 0xc4, 0x16, 0xea, 0x69, 0x8d, 0xe8, 0xd3, 0x7e, 0xcc, 0x03, 0xd8, 0x0a, 0xd8, 0xfb, 0x16, 0x40, - 0xbd, 0xf0, 0x3d, 0x2b, 0xdb, 0x4b, 0xd8, 0x5f, 0xe4, 0x49, 0x8a, 0x9a, 0x4f, 0x65, 0x22, 0xad, - 0xdb, 0x69, 0xd5, 0x97, 0x3f, 0xde, 0x64, 0xf1, 0xf1, 0x11, 0x68, 0xc9, 0xb6, 0x73, 0xc8, 0x2d, - 0x1c, 0xcc, 0xa5, 0x11, 0x2a, 0xbd, 0x93, 0x71, 0xae, 0xf9, 0x4a, 0xcb, 0xae, 0xd0, 0x9f, 0x9b, - 0x85, 0x2e, 0xd0, 0xa2, 0xb0, 0x18, 0x7d, 0xd8, 0x82, 0xb3, 0xa7, 0x05, 0x9c, 0xa4, 0x45, 0xc2, - 0x8d, 0x5b, 0xac, 0xe3, 0x5c, 0x18, 0x84, 0x40, 0xcd, 0xc9, 0x97, 0x06, 0xde, 0xe9, 0xdf, 0xe4, - 0x14, 0xc2, 0x8c, 0x8b, 0x19, 0x8f, 0xd1, 0x09, 0xc6, 0xb5, 0xfd, 0x75, 0xb3, 0xed, 0x4d, 0x11, - 0x65, 0x6b, 0x18, 0x79, 0x0b, 0x6d, 0x91, 0x1b, 0xab, 0xe6, 0x13, 0x8d, 0x46, 0xe5, 0x5a, 0xa0, - 0xa1, 0x0d, 0x9f, 0xfa, 0xdb, 0x66, 0xea, 0xb9, 0x47, 0xb1, 0x12, 0xc4, 0xf6, 0xc5, 0x86, 0x6d, - 0xc8, 0xbf, 0xd0, 0x30, 0x28, 0x34, 0x5a, 0x43, 0xc3, 0x5d, 0xa3, 0x1b, 0xfb, 0xe0, 0x1b, 0x99, - 0x46, 0x32, 0x8d, 0xd9, 0x0a, 0x4b, 0x5e, 0x40, 0x58, 0x7e, 0x00, 0x86, 0x36, 0x7d, 0xde, 0xc9, - 0xee, 0x49, 0x95, 0x2a, 0x62, 0x6b, 0xf8, 0xe8, 0x06, 0x1a, 0xe3, 0x62, 0xeb, 0xe4, 0x12, 0x6a, - 0xee, 0x49, 0x9e, 0xb9, 0x18, 0xe5, 0xd5, 0xea, 0xfc, 0xfe, 0x5c, 0xb8, 0xd0, 0xdf, 0xeb, 0xb3, - 0x4f, 0xa7, 0xb1, 0xb4, 0xf7, 0xf9, 0xd4, 0x35, 0x1f, 0xf2, 0x87, 0x9c, 0x1b, 0x14, 0xb9, 0x96, - 0x76, 0x39, 0xf4, 0x89, 0xc3, 0x47, 0xc7, 0xf4, 0x55, 0xf9, 0x3b, 0xad, 0xfb, 0x0b, 0x79, 0xf6, - 0x3d, 0x00, 0x00, 0xff, 0xff, 0x40, 0xd0, 0xe7, 0xda, 0x6a, 0x05, 0x00, 0x00, + // 710 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x6e, 0xe3, 0x36, + 0x10, 0x86, 0x2d, 0xc7, 0x96, 0xc7, 0x45, 0xe3, 0xb0, 0x4d, 0xa0, 0x38, 0x4d, 0x6b, 0xf8, 0x50, + 0x18, 0x28, 0x60, 0x37, 0x4e, 0x8b, 0xfe, 0xdd, 0x9a, 0xa4, 0x45, 0x8a, 0x16, 0x09, 0xe8, 0xa0, + 0x87, 0x5e, 0x54, 0x9a, 0x9a, 0x28, 0x84, 0x65, 0x49, 0x21, 0x29, 0x01, 0x7e, 0x95, 0x7d, 0xa2, + 0x7d, 0x81, 0x7d, 0x9f, 0x05, 0x49, 0xc9, 0x88, 0xed, 0x64, 0x4f, 0xd2, 0xcc, 0xf7, 0xcd, 0xcc, + 0x47, 0xf2, 0x23, 0xe1, 0x54, 0xe6, 0x7c, 0xaa, 0x38, 0x4b, 0x53, 0x94, 0x53, 0x85, 0xb2, 0x14, + 0x1c, 0x27, 0xb9, 0xcc, 0x74, 0x46, 0xfa, 0x5a, 0x8a, 0x72, 0x3d, 0xa9, 0xc0, 0x49, 0x79, 0x31, + 0x08, 0x0c, 0x99, 0x67, 0xab, 0x55, 0x96, 0x6e, 0x73, 0x47, 0xef, 0x1a, 0xd0, 0x9b, 0x73, 0x96, + 0x52, 0x7c, 0x2e, 0x50, 0x69, 0x72, 0x02, 0x6d, 0xcd, 0x64, 0x8c, 0x3a, 0x68, 0x0c, 0x1b, 0xe3, + 0x2e, 0xad, 0x22, 0xf2, 0x0d, 0xf4, 0x98, 0xd4, 0xe2, 0x91, 0x71, 0x1d, 0x8a, 0x28, 0x68, 0x5a, + 0x10, 0xea, 0xd4, 0x6d, 0x44, 0x4e, 0xc1, 0x5f, 0x24, 0xd9, 0x22, 0x14, 0x91, 0x0a, 0xbc, 0xa1, + 0x37, 0xee, 0xd2, 0x8e, 0x89, 0x6f, 0x23, 0x45, 0x7e, 0x82, 0x4e, 0x96, 0x6b, 0x91, 0xa5, 0x2a, + 0x68, 0x0d, 0x1b, 0xe3, 0xde, 0xec, 0x7c, 0xb2, 0xab, 0x70, 0x62, 0x34, 0xdc, 0x39, 0x12, 0xad, + 0xd9, 0xa3, 0x21, 0xf8, 0x7f, 0x0b, 0x8e, 0xa9, 0x42, 0x45, 0xbe, 0x84, 0x83, 0x94, 0xad, 0x50, + 0x05, 0x0d, 0xdb, 0xdc, 0x05, 0xa3, 0xf7, 0x9e, 0x93, 0x5f, 0x95, 0x92, 0x33, 0xe8, 0xe6, 0xcb, + 0x38, 0xd4, 0xeb, 0x7c, 0xc3, 0xf4, 0xf3, 0x65, 0xfc, 0x60, 0x62, 0x32, 0x00, 0xbf, 0x9a, 0xa8, + 0x82, 0xa6, 0xc3, 0xea, 0x98, 0x70, 0x20, 0x89, 0x1b, 0x15, 0x72, 0xa6, 0x31, 0xce, 0xa4, 0x40, + 0x23, 0xd7, 0x1b, 0xf7, 0x66, 0x3f, 0x7c, 0x52, 0xee, 0xa4, 0x92, 0x78, 0xb5, 0x29, 0xbb, 0x49, + 0xb5, 0x5c, 0xd3, 0xa3, 0x64, 0x37, 0x4f, 0xc6, 0xd0, 0x17, 0x29, 0x4f, 0x8a, 0x08, 0xc3, 0x08, + 0xcb, 0x30, 0xc2, 0x5c, 0x05, 0x07, 0xc3, 0xc6, 0xd8, 0xa7, 0x9f, 0x57, 0xf9, 0x6b, 0x2c, 0xaf, + 0x31, 0x57, 0xe4, 0x3b, 0x38, 0x32, 0xeb, 0x90, 0x98, 0x30, 0x3b, 0xe4, 0x49, 0xe4, 0x2a, 0x68, + 0x5b, 0xcd, 0xfd, 0x7c, 0x19, 0xd3, 0x97, 0x79, 0x32, 0x86, 0x76, 0x24, 0x94, 0x96, 0x59, 0xd0, + 0xb1, 0xdb, 0xdb, 0xaf, 0xf4, 0xba, 0x03, 0x9f, 0xdc, 0xcd, 0x69, 0x85, 0x93, 0x19, 0x1c, 0x97, + 0x45, 0x92, 0x86, 0x0a, 0x4b, 0x94, 0x42, 0xaf, 0x43, 0x95, 0x15, 0x92, 0xa3, 0x0a, 0x7c, 0xdb, + 0xfa, 0x0b, 0x03, 0xce, 0x2b, 0x6c, 0xee, 0xa0, 0xc1, 0xff, 0x70, 0xf2, 0xfa, 0x0a, 0x49, 0x1f, + 0xbc, 0x25, 0xae, 0x2b, 0xa3, 0x98, 0x5f, 0xf2, 0x3d, 0x1c, 0x94, 0x2c, 0x29, 0xd0, 0xfa, 0xa3, + 0x37, 0x1b, 0xec, 0x6f, 0x5c, 0x7d, 0x9e, 0xd4, 0x11, 0x7f, 0x6d, 0xfe, 0xdc, 0xf8, 0xab, 0xe5, + 0x7b, 0xfd, 0xd6, 0x28, 0x82, 0xcf, 0x9c, 0x11, 0x55, 0x9e, 0xa5, 0x0a, 0xc9, 0x10, 0x9a, 0x99, + 0xb2, 0xcd, 0x5f, 0x5b, 0x51, 0x33, 0x53, 0x64, 0x06, 0x1d, 0x89, 0xaa, 0x48, 0xb4, 0x73, 0x5c, + 0x6f, 0x16, 0xec, 0xcf, 0xa3, 0x96, 0x40, 0x6b, 0xe2, 0xe8, 0x83, 0x07, 0x6d, 0x97, 0x7b, 0xd3, + 0xea, 0x37, 0x70, 0x68, 0xf6, 0x01, 0x25, 0x5b, 0x88, 0x44, 0x68, 0xe3, 0x83, 0xa6, 0x6d, 0x7f, + 0xb6, 0xad, 0xe2, 0xdf, 0x17, 0xa4, 0x35, 0xdd, 0xad, 0x21, 0x0f, 0x70, 0xb4, 0x12, 0x8a, 0x67, + 0xe9, 0xa3, 0x88, 0x0b, 0xc9, 0x6a, 0xff, 0x9b, 0x46, 0xdf, 0x6e, 0x37, 0xba, 0x46, 0x8d, 0x5c, + 0x63, 0xf4, 0xcf, 0x0e, 0x9d, 0xee, 0x37, 0x30, 0xd7, 0x80, 0x27, 0x4c, 0x19, 0x33, 0x18, 0xcd, + 0x2e, 0x20, 0x04, 0x5a, 0xc6, 0xf2, 0x81, 0x67, 0x93, 0xf6, 0x9f, 0x5c, 0x80, 0x9f, 0x33, 0xbe, + 0x64, 0x31, 0x1a, 0x93, 0x99, 0xb1, 0xc7, 0xdb, 0x63, 0xef, 0x1d, 0x4a, 0x37, 0x34, 0xf2, 0x27, + 0xf4, 0x79, 0xa1, 0x74, 0xb6, 0x0a, 0x25, 0xd6, 0xce, 0xe8, 0xd8, 0xd2, 0xaf, 0xb6, 0x4b, 0xaf, + 0x2c, 0x8b, 0x56, 0x24, 0x7a, 0xc8, 0xb7, 0x62, 0x45, 0x7e, 0x84, 0x8e, 0x42, 0x2e, 0x51, 0x3b, + 0x67, 0xed, 0x6d, 0xdd, 0xdc, 0x82, 0x7f, 0x88, 0x34, 0x12, 0x69, 0x4c, 0x6b, 0x2e, 0xf9, 0x05, + 0xfc, 0xea, 0xd2, 0xa8, 0xa0, 0x6b, 0xeb, 0xce, 0x5f, 0xdf, 0xa9, 0xca, 0x45, 0x74, 0x43, 0x9f, + 0xdd, 0x43, 0x67, 0xee, 0x4e, 0x9d, 0xdc, 0x40, 0xcb, 0xfc, 0x92, 0x37, 0x5e, 0x99, 0xea, 0xa5, + 0x1b, 0x7c, 0xfd, 0x16, 0xec, 0xfc, 0xf7, 0xfb, 0xe5, 0x7f, 0x17, 0xb1, 0xd0, 0x4f, 0xc5, 0xc2, + 0x0c, 0x9f, 0xb2, 0xe7, 0x82, 0x29, 0xe4, 0x85, 0xb9, 0x19, 0x53, 0x5b, 0x38, 0x7d, 0xf1, 0x00, + 0xff, 0x56, 0x7d, 0x17, 0x6d, 0xfb, 0xaa, 0x5e, 0x7e, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xce, 0x3a, + 0x39, 0x26, 0x9e, 0x05, 0x00, 0x00, }