feat: add --vuln-severity-source flag (#8269)

This commit is contained in:
DmitriyLewen
2025-03-03 16:59:30 +06:00
committed by GitHub
parent 6b4cebe959
commit d464807321
26 changed files with 661 additions and 247 deletions

View File

@@ -100,6 +100,7 @@ trivy filesystem [flags] PATH
--trace enable more verbose trace output for custom queries --trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -121,6 +121,7 @@ trivy image [flags] IMAGE_NAME
--trace enable more verbose trace output for custom queries --trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -114,6 +114,7 @@ trivy kubernetes [flags] [CONTEXT]
--trace enable more verbose trace output for custom queries --trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -99,6 +99,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--trace enable more verbose trace output for custom queries --trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -101,6 +101,7 @@ trivy rootfs [flags] ROOTDIR
--trace enable more verbose trace output for custom queries --trace enable more verbose trace output for custom queries
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -73,6 +73,7 @@ trivy sbom [flags] SBOM_PATH
--token-header string specify a header name for token in client/server mode (default "Trivy-Token") --token-header string specify a header name for token in client/server mode (default "Trivy-Token")
--username strings username. Comma-separated usernames allowed. --username strings username. Comma-separated usernames allowed.
--vex strings [EXPERIMENTAL] VEX sources ("repo", "oci" or file path) --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 ### Options inherited from parent commands

View File

@@ -86,6 +86,7 @@ trivy vm [flags] VM_IMAGE
--token string for authentication in client/server mode --token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token") --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) --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 ### Options inherited from parent commands

View File

@@ -626,6 +626,10 @@ vulnerability:
# Same as '--ignore-unfixed' # Same as '--ignore-unfixed'
ignore-unfixed: false ignore-unfixed: false
# Same as '--vuln-severity-source'
severity-source:
- auto
# Same as '--skip-vex-repo-update' # Same as '--skip-vex-repo-update'
skip-vex-repo-update: false skip-vex-repo-update: false

View File

@@ -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. Also, you may want to specify the OS version when OS is not detected.
For these cases, Trivy supports a `--distro` flag using the `<family>/<version>` format (e.g. `alpine/3.20`) to set the desired OS version. For these cases, Trivy supports a `--distro` flag using the `<family>/<version>` 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 [^1]: https://github.com/GoogleContainerTools/distroless
[nvd-CVE-2023-0464]: https://nvd.nist.gov/vuln/detail/CVE-2023-0464 [nvd-CVE-2023-0464]: https://nvd.nist.gov/vuln/detail/CVE-2023-0464

View File

@@ -37,6 +37,7 @@ type csArgs struct {
Target string Target string
secretConfig string secretConfig string
Distro string Distro string
VulnSeveritySources []string
} }
func TestClientServer(t *testing.T) { func TestClientServer(t *testing.T) {
@@ -280,6 +281,19 @@ func TestClientServer(t *testing.T) {
}, },
golden: "testdata/npm.json.golden", 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", name: "scan sample.pem with repo command in client/server mode",
args: csArgs{ 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 { if len(c.IgnoreIDs) != 0 {
trivyIgnore := filepath.Join(t.TempDir(), ".trivyignore") trivyIgnore := filepath.Join(t.TempDir(), ".trivyignore")
err := os.WriteFile(trivyIgnore, []byte(strings.Join(c.IgnoreIDs, "\n")), 0444) err := os.WriteFile(trivyIgnore, []byte(strings.Join(c.IgnoreIDs, "\n")), 0444)

View File

@@ -35,6 +35,7 @@ func TestRepository(t *testing.T) {
includeDevDeps bool includeDevDeps bool
parallel int parallel int
vex string vex string
vulnSeveritySources []string
} }
tests := []struct { tests := []struct {
name string name string
@@ -104,6 +105,18 @@ func TestRepository(t *testing.T) {
}, },
golden: "testdata/npm.json.golden", 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", name: "npm with dev deps",
args: args{ 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 { if tt.args.listAllPkgs {
osArgs = append(osArgs, "--list-all-pkgs") osArgs = append(osArgs, "--list-all-pkgs")
} }

View File

@@ -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"
}
]
}
]
}

View File

@@ -463,6 +463,7 @@ func (o *Options) ScanOpts() types.ScanOptions {
FilePatterns: o.FilePatterns, FilePatterns: o.FilePatterns,
IncludeDevDeps: o.IncludeDevDeps, IncludeDevDeps: o.IncludeDevDeps,
Distro: o.Distro, Distro: o.Distro,
VulnSeveritySources: o.VulnSeveritySources,
} }
} }

View File

@@ -4,8 +4,10 @@ import (
"github.com/samber/lo" "github.com/samber/lo"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types" 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/log"
"github.com/aquasecurity/trivy/pkg/vex" "github.com/aquasecurity/trivy/pkg/vex"
xstrings "github.com/aquasecurity/trivy/pkg/x/strings"
) )
var ( var (
@@ -30,6 +32,15 @@ var (
ConfigName: "vulnerability.skip-vex-repo-update", ConfigName: "vulnerability.skip-vex-repo-update",
Usage: `[EXPERIMENTAL] Skip VEX Repository 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 { type VulnerabilityFlagGroup struct {
@@ -37,12 +48,14 @@ type VulnerabilityFlagGroup struct {
IgnoreStatus *Flag[[]string] IgnoreStatus *Flag[[]string]
VEX *Flag[[]string] VEX *Flag[[]string]
SkipVEXRepoUpdate *Flag[bool] SkipVEXRepoUpdate *Flag[bool]
VulnSeveritySource *Flag[[]string]
} }
type VulnerabilityOptions struct { type VulnerabilityOptions struct {
IgnoreStatuses []dbTypes.Status IgnoreStatuses []dbTypes.Status
VEXSources []vex.Source VEXSources []vex.Source
SkipVEXRepoUpdate bool SkipVEXRepoUpdate bool
VulnSeveritySources []dbTypes.SourceID
} }
func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup { func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup {
@@ -51,6 +64,7 @@ func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup {
IgnoreStatus: IgnoreStatusFlag.Clone(), IgnoreStatus: IgnoreStatusFlag.Clone(),
VEX: VEXFlag.Clone(), VEX: VEXFlag.Clone(),
SkipVEXRepoUpdate: SkipVEXRepoUpdateFlag.Clone(), SkipVEXRepoUpdate: SkipVEXRepoUpdateFlag.Clone(),
VulnSeveritySource: VulnSeveritySourceFlag.Clone(),
} }
} }
@@ -64,6 +78,7 @@ func (f *VulnerabilityFlagGroup) Flags() []Flagger {
f.IgnoreStatus, f.IgnoreStatus,
f.VEX, f.VEX,
f.SkipVEXRepoUpdate, f.SkipVEXRepoUpdate,
f.VulnSeveritySource,
} }
} }
@@ -101,5 +116,6 @@ func (f *VulnerabilityFlagGroup) ToOptions() (VulnerabilityOptions, error) {
return vex.NewSource(s) return vex.NewSource(s)
}), }),
SkipVEXRepoUpdate: f.SkipVEXRepoUpdate.Value(), SkipVEXRepoUpdate: f.SkipVEXRepoUpdate.Value(),
VulnSeveritySources: xstrings.ToTSlice[dbTypes.SourceID](f.VulnSeveritySource.Value()),
}, nil }, nil
} }

View File

@@ -99,6 +99,7 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys
LicenseCategories: licenseCategories, LicenseCategories: licenseCategories,
IncludeDevDeps: opts.IncludeDevDeps, IncludeDevDeps: opts.IncludeDevDeps,
Distro: distro, Distro: distro,
VulnSeveritySources: xstrings.ToStringSlice(opts.VulnSeveritySources),
}, },
}) })
return err return err

View File

@@ -8,6 +8,7 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/emptypb"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/cache" "github.com/aquasecurity/trivy/pkg/cache"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
@@ -15,6 +16,7 @@ import (
"github.com/aquasecurity/trivy/pkg/scanner" "github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/scanner/local" "github.com/aquasecurity/trivy/pkg/scanner/local"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
xstrings "github.com/aquasecurity/trivy/pkg/x/strings"
rpcCache "github.com/aquasecurity/trivy/rpc/cache" rpcCache "github.com/aquasecurity/trivy/rpc/cache"
rpcScanner "github.com/aquasecurity/trivy/rpc/scanner" rpcScanner "github.com/aquasecurity/trivy/rpc/scanner"
) )
@@ -81,6 +83,13 @@ func (s *ScanServer) ToOptions(in *rpcScanner.ScanOptions) types.ScanOptions {
distro.Name = in.Distro.Name 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{ return types.ScanOptions{
PkgTypes: in.PkgTypes, PkgTypes: in.PkgTypes,
PkgRelationships: pkgRelationships, PkgRelationships: pkgRelationships,
@@ -88,6 +97,7 @@ func (s *ScanServer) ToOptions(in *rpcScanner.ScanOptions) types.ScanOptions {
IncludeDevDeps: in.IncludeDevDeps, IncludeDevDeps: in.IncludeDevDeps,
LicenseCategories: licenseCategories, LicenseCategories: licenseCategories,
Distro: distro, Distro: distro,
VulnSeveritySources: vulnSeveritySources,
} }
} }

View File

@@ -49,6 +49,7 @@ func TestScanServer_Scan(t *testing.T) {
PkgTypes: []string{types.PkgTypeOS}, PkgTypes: []string{types.PkgTypeOS},
Scanners: []string{string(types.VulnerabilityScanner)}, Scanners: []string{string(types.VulnerabilityScanner)},
PkgRelationships: []string{ftypes.RelationshipUnknown.String()}, PkgRelationships: []string{ftypes.RelationshipUnknown.String()},
VulnSeveritySources: []string{"auto"},
}, },
}, },
}, },

View File

@@ -145,7 +145,7 @@ func (s Scanner) ScanTarget(ctx context.Context, target types.ScanTarget, option
for i := range results { for i := range results {
// Fill vulnerability details // Fill vulnerability details
s.vulnClient.FillInfo(results[i].Vulnerabilities) s.vulnClient.FillInfo(results[i].Vulnerabilities, options.VulnSeveritySources)
} }
// Post scanning // Post scanning

View File

@@ -169,6 +169,7 @@ func TestScanner_Scan(t *testing.T) {
}, },
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -279,6 +280,7 @@ func TestScanner_Scan(t *testing.T) {
Family: "alpine", Family: "alpine",
Name: "3.11", Name: "3.11",
}, },
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -456,6 +458,7 @@ func TestScanner_Scan(t *testing.T) {
}, },
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -535,6 +538,7 @@ func TestScanner_Scan(t *testing.T) {
PkgTypes: []string{types.PkgTypeLibrary}, PkgTypes: []string{types.PkgTypeLibrary},
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -644,6 +648,7 @@ func TestScanner_Scan(t *testing.T) {
}, },
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -724,6 +729,7 @@ func TestScanner_Scan(t *testing.T) {
}, },
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},
@@ -822,6 +828,7 @@ func TestScanner_Scan(t *testing.T) {
ftypes.RelationshipIndirect, ftypes.RelationshipIndirect,
}, },
Scanners: types.Scanners{types.VulnerabilityScanner}, Scanners: types.Scanners{types.VulnerabilityScanner},
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
fixtures: []string{"testdata/fixtures/happy.yaml"}, fixtures: []string{"testdata/fixtures/happy.yaml"},

View File

@@ -46,6 +46,7 @@ func TestScanner_ScanArtifact(t *testing.T) {
PkgTypes: []string{"os"}, PkgTypes: []string{"os"},
Scanners: tTypes.Scanners{tTypes.VulnerabilityScanner}, Scanners: tTypes.Scanners{tTypes.VulnerabilityScanner},
PkgRelationships: ftypes.Relationships, PkgRelationships: ftypes.Relationships,
VulnSeveritySources: []dbTypes.SourceID{"auto"},
}, },
}, },
imagePath: "../fanal/test/testdata/alpine-311.tar.gz", imagePath: "../fanal/test/testdata/alpine-311.tar.gz",

View File

@@ -3,6 +3,7 @@ package types
import ( import (
"slices" "slices"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/types"
) )
@@ -122,4 +123,5 @@ type ScanOptions struct {
FilePatterns []string FilePatterns []string
IncludeDevDeps bool IncludeDevDeps bool
Distro types.OS // Forced OS Distro types.OS // Forced OS
VulnSeveritySources []dbTypes.SourceID
} }

View File

@@ -1,6 +1,7 @@
package vulnerability package vulnerability
import ( import (
"slices"
"strings" "strings"
"sync" "sync"
@@ -67,7 +68,8 @@ func NewClient(dbc db.Operation) Client {
} }
// FillInfo fills extra info in vulnerability objects // 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 { for i := range vulns {
// Add the vulnerability status // Add the vulnerability status
// Some vendors such as Red Hat have their own vulnerability status, and we use it. // 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) dataSource := lo.FromPtr(vulns[i].DataSource)
// Select the severity according to the detected sourceID. // 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. // The vendor might provide package-specific severity like Debian.
// For example, CVE-2015-2328 in Debian has "unimportant" for mongodb and "low" for pcre3. // 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].SeveritySource = severitySource
vulns[i].PrimaryURL = c.getPrimaryURL(vulnID, vuln.References, dataSource.ID) 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 { if vs, ok := vuln.VendorSeverity[dataSource.ID]; ok {
return vs.String(), dataSource.ID return vs.String(), dataSource.ID
} }
// use severity from GitHub for all GHSA-xxx vulnerabilities // use severity from GitHub for all GHSA-xxx vulnerabilities
if strings.HasPrefix(vulnID, "GHSA-") { if strings.HasPrefix(vulnID, "GHSA-") {
if vs, ok := vuln.VendorSeverity[vulnerability.GHSA]; ok { // use severity from GitHub for all GHSA-IDs
return vs.String(), vulnerability.GHSA autoSeveritySrcs = []dbTypes.SourceID{dataSource.ID, vulnerability.GHSA, vulnerability.NVD}
}
} }
// Try NVD as a fallback if it exists if severity, severitySource := c.getSeverity(vulnID, vuln, dataSource, autoSeveritySrcs); severity != dbTypes.SeverityUnknown.String() {
if vs, ok := vuln.VendorSeverity[vulnerability.NVD]; ok { return severity, severitySource
return vs.String(), vulnerability.NVD
} }
if vuln.Severity == "" { if vuln.Severity == "" {

View File

@@ -17,6 +17,7 @@ import (
func TestClient_FillInfo(t *testing.T) { func TestClient_FillInfo(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
vulnSeveritySources []dbTypes.SourceID
fixtures []string fixtures []string
vulns []types.DetectedVulnerability vulns []types.DetectedVulnerability
expectedVulnerabilities []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", name: "GetVulnerability returns an error",
fixtures: []string{"testdata/fixtures/sad.yaml"}, fixtures: []string{"testdata/fixtures/sad.yaml"},
@@ -306,7 +395,13 @@ func TestClient_FillInfo(t *testing.T) {
defer db.Close() defer db.Close()
c := vuln.NewClient(db.Config{}) 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) assert.Equal(t, tt.expectedVulnerabilities, tt.vulns, tt.name)
}) })
} }

View File

@@ -152,6 +152,7 @@ type ScanOptions struct {
IncludeDevDeps bool `protobuf:"varint,5,opt,name=include_dev_deps,json=includeDevDeps,proto3" json:"include_dev_deps,omitempty"` 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"` 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"` 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() { func (x *ScanOptions) Reset() {
@@ -228,6 +229,13 @@ func (x *ScanOptions) GetDistro() *common.OS {
return nil return nil
} }
func (x *ScanOptions) GetVulnSeveritySources() []string {
if x != nil {
return x.VulnSeveritySources
}
return nil
}
type ScanResponse struct { type ScanResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x69, 0x73, 0x74, 0x72, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x73, 0x65,
0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x08,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x76, 0x75, 0x6c, 0x6e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69,
0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x74, 0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x60, 0x0a, 0x16, 0x4c, 0x69, 0x63,
0x32, 0x1a, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e,
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x64, 0x0a, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x0c, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61,
0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73,
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4f, 0x53, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10,
0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x04, 0x22, 0x64, 0x0a, 0x0c, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e,
0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4f, 0x53, 0x52,
0x6c, 0x74, 0x73, 0x22, 0xd5, 0x03, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x02, 0x6f, 0x73, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03,
0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61,
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x45, 0x0a, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07,
0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xd5, 0x03, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75,
0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x56, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01,
0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0f, 0x76, 0x75, 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, 0x12, 0x54, 0x0a, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20,
0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x6f, 0x6e, 0x2e, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65,
0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x54, 0x0a, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
0x52, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74,
0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65,
0x28, 0x09, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x6d, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73,
0x15, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a,
0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
0x12, 0x47, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20,
0x72, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x69, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x72,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c,
0x72, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x69, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x75,
0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0f, 0x63, 0x75,
0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a,
0x12, 0x39, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b,
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x65,
0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x74, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x63,
0x65, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x32, 0x50, 0x0a, 0x07, 0x53, 0x72, 0x65, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73,
0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x1d, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x63,
0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4c, 0x69,
0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x32,
0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x50, 0x0a, 0x07, 0x53, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x63,
0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x61, 0x6e, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e,
0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x71, 0x75, 0x61, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2f, 0x72, 0x74, 0x1a, 0x1e, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65,
0x70, 0x63, 0x2f, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 ( var (

View File

@@ -29,6 +29,7 @@ message ScanOptions {
bool include_dev_deps = 5; bool include_dev_deps = 5;
repeated string pkg_relationships = 6; repeated string pkg_relationships = 6;
common.OS distro = 7; common.OS distro = 7;
repeated string vuln_severity_sources = 8;
reserved 3; // deleted 'list_all_packages' reserved 3; // deleted 'list_all_packages'
} }

View File

@@ -1094,48 +1094,50 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error)
} }
var twirpFileDescriptor0 = []byte{ var twirpFileDescriptor0 = []byte{
// 685 bytes of a gzipped FileDescriptorProto // 710 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0x51, 0x6f, 0x1a, 0x47, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x6e, 0xe3, 0x36,
0x10, 0x16, 0x1c, 0x86, 0x63, 0xa8, 0x6a, 0xbc, 0x6a, 0xad, 0x35, 0xae, 0x5b, 0xc4, 0x43, 0x85, 0x10, 0x86, 0x2d, 0xc7, 0x96, 0xc7, 0x45, 0xe3, 0xb0, 0x4d, 0xa0, 0x38, 0x4d, 0x6b, 0xf8, 0x50,
0x54, 0x09, 0x6a, 0xdc, 0xaa, 0x4d, 0xf2, 0x16, 0xdb, 0x89, 0x1c, 0x25, 0xb2, 0xb5, 0x58, 0x79, 0x18, 0x28, 0x60, 0x37, 0x4e, 0x8b, 0xfe, 0xdd, 0x9a, 0xa4, 0x45, 0x8a, 0x16, 0x09, 0xe8, 0xa0,
0xc8, 0x0b, 0x59, 0xf6, 0xc6, 0xe7, 0x15, 0xc7, 0xed, 0x79, 0x77, 0x0f, 0x89, 0xff, 0x91, 0xa7, 0x87, 0x5e, 0x54, 0x9a, 0x9a, 0x28, 0x84, 0x65, 0x49, 0x21, 0x29, 0x01, 0x7e, 0x95, 0x7d, 0xa2,
0xfc, 0xaf, 0xfc, 0x9f, 0x68, 0xf7, 0x0e, 0x64, 0x30, 0xce, 0x13, 0x3b, 0x33, 0xdf, 0xcc, 0x7c, 0x7d, 0x81, 0x7d, 0x9f, 0x05, 0x49, 0xc9, 0x88, 0xed, 0x64, 0x4f, 0xd2, 0xcc, 0xf7, 0xcd, 0xcc,
0xcc, 0x7c, 0x37, 0x70, 0xa4, 0x33, 0x31, 0x34, 0x82, 0xa7, 0x29, 0xea, 0xa1, 0x41, 0xbd, 0x90, 0x47, 0xf2, 0x23, 0xe1, 0x54, 0xe6, 0x7c, 0xaa, 0x38, 0x4b, 0x53, 0x94, 0x53, 0x85, 0xb2, 0x14,
0x02, 0x07, 0x99, 0x56, 0x56, 0x91, 0xb6, 0xd5, 0x72, 0xb1, 0x1c, 0x94, 0xc1, 0xc1, 0xe2, 0xb4, 0x1c, 0x27, 0xb9, 0xcc, 0x74, 0x46, 0xfa, 0x5a, 0x8a, 0x72, 0x3d, 0xa9, 0xc0, 0x49, 0x79, 0x31,
0x43, 0x1d, 0x58, 0xa8, 0xf9, 0x5c, 0xa5, 0x9b, 0xd8, 0xde, 0xd7, 0x0a, 0xb4, 0xc6, 0x82, 0xa7, 0x08, 0x0c, 0x99, 0x67, 0xab, 0x55, 0x96, 0x6e, 0x73, 0x47, 0xef, 0x1a, 0xd0, 0x9b, 0x73, 0x96,
0x0c, 0x1f, 0x72, 0x34, 0x96, 0x1c, 0x42, 0xdd, 0x72, 0x1d, 0xa3, 0xa5, 0x95, 0x6e, 0xa5, 0xdf, 0x52, 0x7c, 0x2e, 0x50, 0x69, 0x72, 0x02, 0x6d, 0xcd, 0x64, 0x8c, 0x3a, 0x68, 0x0c, 0x1b, 0xe3,
0x64, 0xa5, 0x45, 0xfe, 0x80, 0x16, 0xd7, 0x56, 0xde, 0x71, 0x61, 0x27, 0x32, 0xa2, 0x55, 0x1f, 0x2e, 0xad, 0x22, 0xf2, 0x0d, 0xf4, 0x98, 0xd4, 0xe2, 0x91, 0x71, 0x1d, 0x8a, 0x28, 0x68, 0x5a,
0x84, 0x95, 0xeb, 0x2a, 0x22, 0x47, 0x10, 0x4e, 0x13, 0x35, 0x9d, 0xc8, 0xc8, 0xd0, 0xa0, 0x1b, 0x10, 0xea, 0xd4, 0x6d, 0x44, 0x4e, 0xc1, 0x5f, 0x24, 0xd9, 0x22, 0x14, 0x91, 0x0a, 0xbc, 0xa1,
0xf4, 0x9b, 0xac, 0xe1, 0xec, 0xab, 0xc8, 0x90, 0xff, 0xa0, 0xa1, 0x32, 0x2b, 0x55, 0x6a, 0x68, 0x37, 0xee, 0xd2, 0x8e, 0x89, 0x6f, 0x23, 0x45, 0x7e, 0x82, 0x4e, 0x96, 0x6b, 0x91, 0xa5, 0x2a,
0xad, 0x5b, 0xe9, 0xb7, 0x46, 0x27, 0x83, 0x6d, 0x86, 0x03, 0xc7, 0xe1, 0xba, 0x00, 0xb1, 0x15, 0x68, 0x0d, 0x1b, 0xe3, 0xde, 0xec, 0x7c, 0xb2, 0xab, 0x70, 0x62, 0x34, 0xdc, 0x39, 0x12, 0xad,
0xba, 0xd7, 0x85, 0xf0, 0xbd, 0x14, 0x98, 0x1a, 0x34, 0xe4, 0x17, 0xd8, 0x4b, 0xf9, 0x1c, 0x0d, 0xd9, 0xa3, 0x21, 0xf8, 0x7f, 0x0b, 0x8e, 0xa9, 0x42, 0x45, 0xbe, 0x84, 0x83, 0x94, 0xad, 0x50,
0xad, 0xf8, 0xe2, 0x85, 0xd1, 0xfb, 0x12, 0x14, 0xf4, 0xcb, 0x54, 0x72, 0x0c, 0xcd, 0x6c, 0x16, 0x05, 0x0d, 0xdb, 0xdc, 0x05, 0xa3, 0xf7, 0x9e, 0x93, 0x5f, 0x95, 0x92, 0x33, 0xe8, 0xe6, 0xcb,
0x4f, 0xec, 0x32, 0x5b, 0x23, 0xc3, 0x6c, 0x16, 0xdf, 0x3a, 0x9b, 0x74, 0x20, 0x2c, 0x3b, 0x1a, 0x38, 0xd4, 0xeb, 0x7c, 0xc3, 0xf4, 0xf3, 0x65, 0xfc, 0x60, 0x62, 0x32, 0x00, 0xbf, 0x9a, 0xa8,
0x5a, 0x2d, 0x62, 0x2b, 0x9b, 0x08, 0x20, 0x49, 0xd1, 0x6a, 0x22, 0xb8, 0xc5, 0x58, 0x69, 0x89, 0x82, 0xa6, 0xc3, 0xea, 0x98, 0x70, 0x20, 0x89, 0x1b, 0x15, 0x72, 0xa6, 0x31, 0xce, 0xa4, 0x40,
0x8e, 0x6e, 0xd0, 0x6f, 0x8d, 0xfe, 0xf9, 0x21, 0xdd, 0x41, 0x49, 0xf1, 0x7c, 0x9d, 0x76, 0x99, 0x23, 0xd7, 0x1b, 0xf7, 0x66, 0x3f, 0x7c, 0x52, 0xee, 0xa4, 0x92, 0x78, 0xb5, 0x29, 0xbb, 0x49,
0x5a, 0xbd, 0x64, 0x07, 0xc9, 0xb6, 0x9f, 0xf4, 0xa1, 0x2d, 0x53, 0x91, 0xe4, 0x11, 0x4e, 0x22, 0xb5, 0x5c, 0xd3, 0xa3, 0x64, 0x37, 0x4f, 0xc6, 0xd0, 0x17, 0x29, 0x4f, 0x8a, 0x08, 0xc3, 0x08,
0x5c, 0x4c, 0x22, 0xcc, 0x0c, 0xdd, 0xeb, 0x56, 0xfa, 0x21, 0xfb, 0xb9, 0xf4, 0x5f, 0xe0, 0xe2, 0xcb, 0x30, 0xc2, 0x5c, 0x05, 0x07, 0xc3, 0xc6, 0xd8, 0xa7, 0x9f, 0x57, 0xf9, 0x6b, 0x2c, 0xaf,
0x02, 0x33, 0x43, 0xfe, 0x82, 0x03, 0xf7, 0x3f, 0x34, 0x26, 0xdc, 0x37, 0xb9, 0x97, 0x99, 0xa1, 0x31, 0x57, 0xe4, 0x3b, 0x38, 0x32, 0xeb, 0x90, 0x98, 0x30, 0x3b, 0xe4, 0x49, 0xe4, 0x2a, 0x68,
0x75, 0xcf, 0xb9, 0x9d, 0xcd, 0x62, 0xf6, 0xd8, 0x4f, 0xfa, 0x50, 0x8f, 0xa4, 0xb1, 0x5a, 0xd1, 0x5b, 0xcd, 0xfd, 0x7c, 0x19, 0xd3, 0x97, 0x79, 0x32, 0x86, 0x76, 0x24, 0x94, 0x96, 0x59, 0xd0,
0x86, 0x1f, 0x6f, 0xbb, 0xe4, 0x5b, 0x2c, 0x7c, 0x70, 0x3d, 0x66, 0x65, 0xbc, 0xf3, 0x19, 0x0e, 0xb1, 0xdb, 0xdb, 0xaf, 0xf4, 0xba, 0x03, 0x9f, 0xdc, 0xcd, 0x69, 0x85, 0x93, 0x19, 0x1c, 0x97,
0x77, 0xb3, 0x25, 0x6d, 0x08, 0x66, 0xb8, 0x2c, 0x97, 0xee, 0x9e, 0xe4, 0x6f, 0xd8, 0x5b, 0xf0, 0x45, 0x92, 0x86, 0x0a, 0x4b, 0x94, 0x42, 0xaf, 0x43, 0x95, 0x15, 0x92, 0xa3, 0x0a, 0x7c, 0xdb,
0x24, 0x47, 0xbf, 0xeb, 0xd6, 0xa8, 0xf3, 0x74, 0x08, 0xab, 0xdd, 0xb0, 0x02, 0xf8, 0xb2, 0xfa, 0xfa, 0x0b, 0x03, 0xce, 0x2b, 0x6c, 0xee, 0xa0, 0xc1, 0xff, 0x70, 0xf2, 0xfa, 0x0a, 0x49, 0x1f,
0x7f, 0xe5, 0x5d, 0x2d, 0x0c, 0xda, 0xb5, 0x5e, 0x04, 0x3f, 0x15, 0xa2, 0x32, 0x99, 0x4a, 0x0d, 0xbc, 0x25, 0xae, 0x2b, 0xa3, 0x98, 0x5f, 0xf2, 0x3d, 0x1c, 0x94, 0x2c, 0x29, 0xd0, 0xfa, 0xa3,
0x92, 0x2e, 0x54, 0x95, 0xf1, 0xc5, 0x77, 0xb1, 0xab, 0x2a, 0x43, 0x46, 0xd0, 0xd0, 0x68, 0xf2, 0x37, 0x1b, 0xec, 0x6f, 0x5c, 0x7d, 0x9e, 0xd4, 0x11, 0x7f, 0x6d, 0xfe, 0xdc, 0xf8, 0xab, 0xe5,
0xc4, 0x16, 0xea, 0x69, 0x8d, 0xe8, 0xd3, 0x7e, 0xcc, 0x03, 0xd8, 0x0a, 0xd8, 0xfb, 0x16, 0x40, 0x7b, 0xfd, 0xd6, 0x28, 0x82, 0xcf, 0x9c, 0x11, 0x55, 0x9e, 0xa5, 0x0a, 0xc9, 0x10, 0x9a, 0x99,
0xbd, 0xf0, 0x3d, 0x2b, 0xdb, 0x4b, 0xd8, 0x5f, 0xe4, 0x49, 0x8a, 0x9a, 0x4f, 0x65, 0x22, 0xad, 0xb2, 0xcd, 0x5f, 0x5b, 0x51, 0x33, 0x53, 0x64, 0x06, 0x1d, 0x89, 0xaa, 0x48, 0xb4, 0x73, 0x5c,
0xdb, 0x69, 0xd5, 0x97, 0x3f, 0xde, 0x64, 0xf1, 0xf1, 0x11, 0x68, 0xc9, 0xb6, 0x73, 0xc8, 0x2d, 0x6f, 0x16, 0xec, 0xcf, 0xa3, 0x96, 0x40, 0x6b, 0xe2, 0xe8, 0x83, 0x07, 0x6d, 0x97, 0x7b, 0xd3,
0x1c, 0xcc, 0xa5, 0x11, 0x2a, 0xbd, 0x93, 0x71, 0xae, 0xf9, 0x4a, 0xcb, 0xae, 0xd0, 0x9f, 0x9b, 0xea, 0x37, 0x70, 0x68, 0xf6, 0x01, 0x25, 0x5b, 0x88, 0x44, 0x68, 0xe3, 0x83, 0xa6, 0x6d, 0x7f,
0x85, 0x2e, 0xd0, 0xa2, 0xb0, 0x18, 0x7d, 0xd8, 0x82, 0xb3, 0xa7, 0x05, 0x9c, 0xa4, 0x45, 0xc2, 0xb6, 0xad, 0xe2, 0xdf, 0x17, 0xa4, 0x35, 0xdd, 0xad, 0x21, 0x0f, 0x70, 0xb4, 0x12, 0x8a, 0x67,
0x8d, 0x5b, 0xac, 0xe3, 0x5c, 0x18, 0x84, 0x40, 0xcd, 0xc9, 0x97, 0x06, 0xde, 0xe9, 0xdf, 0xe4, 0xe9, 0xa3, 0x88, 0x0b, 0xc9, 0x6a, 0xff, 0x9b, 0x46, 0xdf, 0x6e, 0x37, 0xba, 0x46, 0x8d, 0x5c,
0x14, 0xc2, 0x8c, 0x8b, 0x19, 0x8f, 0xd1, 0x09, 0xc6, 0xb5, 0xfd, 0x75, 0xb3, 0xed, 0x4d, 0x11, 0x63, 0xf4, 0xcf, 0x0e, 0x9d, 0xee, 0x37, 0x30, 0xd7, 0x80, 0x27, 0x4c, 0x19, 0x33, 0x18, 0xcd,
0x65, 0x6b, 0x18, 0x79, 0x0b, 0x6d, 0x91, 0x1b, 0xab, 0xe6, 0x13, 0x8d, 0x46, 0xe5, 0x5a, 0xa0, 0x2e, 0x20, 0x04, 0x5a, 0xc6, 0xf2, 0x81, 0x67, 0x93, 0xf6, 0x9f, 0x5c, 0x80, 0x9f, 0x33, 0xbe,
0xa1, 0x0d, 0x9f, 0xfa, 0xdb, 0x66, 0xea, 0xb9, 0x47, 0xb1, 0x12, 0xc4, 0xf6, 0xc5, 0x86, 0x6d, 0x64, 0x31, 0x1a, 0x93, 0x99, 0xb1, 0xc7, 0xdb, 0x63, 0xef, 0x1d, 0x4a, 0x37, 0x34, 0xf2, 0x27,
0xc8, 0xbf, 0xd0, 0x30, 0x28, 0x34, 0x5a, 0x43, 0xc3, 0x5d, 0xa3, 0x1b, 0xfb, 0xe0, 0x1b, 0x99, 0xf4, 0x79, 0xa1, 0x74, 0xb6, 0x0a, 0x25, 0xd6, 0xce, 0xe8, 0xd8, 0xd2, 0xaf, 0xb6, 0x4b, 0xaf,
0x46, 0x32, 0x8d, 0xd9, 0x0a, 0x4b, 0x5e, 0x40, 0x58, 0x7e, 0x00, 0x86, 0x36, 0x7d, 0xde, 0xc9, 0x2c, 0x8b, 0x56, 0x24, 0x7a, 0xc8, 0xb7, 0x62, 0x45, 0x7e, 0x84, 0x8e, 0x42, 0x2e, 0x51, 0x3b,
0xee, 0x49, 0x95, 0x2a, 0x62, 0x6b, 0xf8, 0xe8, 0x06, 0x1a, 0xe3, 0x62, 0xeb, 0xe4, 0x12, 0x6a, 0x67, 0xed, 0x6d, 0xdd, 0xdc, 0x82, 0x7f, 0x88, 0x34, 0x12, 0x69, 0x4c, 0x6b, 0x2e, 0xf9, 0x05,
0xee, 0x49, 0x9e, 0xb9, 0x18, 0xe5, 0xd5, 0xea, 0xfc, 0xfe, 0x5c, 0xb8, 0xd0, 0xdf, 0xeb, 0xb3, 0xfc, 0xea, 0xd2, 0xa8, 0xa0, 0x6b, 0xeb, 0xce, 0x5f, 0xdf, 0xa9, 0xca, 0x45, 0x74, 0x43, 0x9f,
0x4f, 0xa7, 0xb1, 0xb4, 0xf7, 0xf9, 0xd4, 0x35, 0x1f, 0xf2, 0x87, 0x9c, 0x1b, 0x14, 0xb9, 0x96, 0xdd, 0x43, 0x67, 0xee, 0x4e, 0x9d, 0xdc, 0x40, 0xcb, 0xfc, 0x92, 0x37, 0x5e, 0x99, 0xea, 0xa5,
0x76, 0x39, 0xf4, 0x89, 0xc3, 0x47, 0xc7, 0xf4, 0x55, 0xf9, 0x3b, 0xad, 0xfb, 0x0b, 0x79, 0xf6, 0x1b, 0x7c, 0xfd, 0x16, 0xec, 0xfc, 0xf7, 0xfb, 0xe5, 0x7f, 0x17, 0xb1, 0xd0, 0x4f, 0xc5, 0xc2,
0x3d, 0x00, 0x00, 0xff, 0xff, 0x40, 0xd0, 0xe7, 0xda, 0x6a, 0x05, 0x00, 0x00, 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,
} }