mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-23 07:29:00 -08:00
refactor: rename security-checks to scanners (#3467)
This commit is contained in:
@@ -54,7 +54,7 @@ Trivy is integrated with many popular platforms and applications. The complete l
|
||||
### General usage
|
||||
|
||||
```bash
|
||||
trivy <target> [--security-checks <scanner1,scanner2>] <subject>
|
||||
trivy <target> [--scanners <scanner1,scanner2>] <subject>
|
||||
```
|
||||
|
||||
Examples:
|
||||
@@ -71,7 +71,7 @@ https://user-images.githubusercontent.com/1161307/171013513-95f18734-233d-45d3-a
|
||||
</details>
|
||||
|
||||
```bash
|
||||
trivy fs --security-checks vuln,secret,config myproject/
|
||||
trivy fs --scanners vuln,secret,config myproject/
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
@@ -21,7 +21,7 @@ You need to pass `--sbom-sources rekor` so that Trivy will look for SBOM attesta
|
||||
$ trivy image --sbom-sources rekor otms61/alpine:3.7.3 [~/src/github.com/aquasecurity/trivy]
|
||||
2022-09-16T17:37:13.258+0900 INFO Vulnerability scanning is enabled
|
||||
2022-09-16T17:37:13.258+0900 INFO Secret scanning is enabled
|
||||
2022-09-16T17:37:13.258+0900 INFO If your scanning is slow, please try '--security-checks vuln' to disable secret scanning
|
||||
2022-09-16T17:37:13.258+0900 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning
|
||||
2022-09-16T17:37:13.258+0900 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
|
||||
2022-09-16T17:37:14.827+0900 INFO Detected SBOM format: cyclonedx-json
|
||||
2022-09-16T17:37:14.901+0900 INFO Found SBOM (cyclonedx) attestation in Rekor
|
||||
@@ -105,7 +105,7 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
Also, it is applied to non-packaged binaries even in container images.
|
||||
|
||||
```bash
|
||||
$ trivy image --sbom-sources rekor --security-checks vuln alpine-with-bat
|
||||
$ trivy image --sbom-sources rekor --scanners vuln alpine-with-bat
|
||||
2022-10-25T13:40:14.920+0300 INFO Vulnerability scanning is enabled
|
||||
2022-10-25T13:40:18.047+0300 INFO Found SBOM attestation in Rekor: bat
|
||||
2022-10-25T13:40:18.186+0300 INFO Detected OS: alpine
|
||||
|
||||
@@ -27,12 +27,12 @@ Filter by severity:
|
||||
$ trivy k8s --severity=CRITICAL --report=all cluster
|
||||
```
|
||||
|
||||
Filter by security check (Vulnerabilities, Secrets or Misconfigurations):
|
||||
Filter by scanners (Vulnerabilities, Secrets or Misconfigurations):
|
||||
|
||||
```
|
||||
$ trivy k8s --security-checks=secret --report=summary cluster
|
||||
$ trivy k8s --scanners=secret --report=summary cluster
|
||||
# or
|
||||
$ trivy k8s --security-checks=config --report=summary cluster
|
||||
$ trivy k8s --scanners=config --report=summary cluster
|
||||
```
|
||||
|
||||
Scan a specific namespace:
|
||||
@@ -263,16 +263,16 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN
|
||||
The infra checks are based on CIS Benchmarks recommendations for kubernetes.
|
||||
|
||||
|
||||
If you want filter only for the infra checks, you can use the flag `--components` along with the `--security-checks=config`
|
||||
If you want filter only for the infra checks, you can use the flag `--components` along with the `--scanners=config`
|
||||
|
||||
```
|
||||
$ trivy k8s cluster --report summary --components=infra --security-checks=config # scan only infra
|
||||
$ trivy k8s cluster --report summary --components=infra --scanners=config # scan only infra
|
||||
```
|
||||
|
||||
Or, to filter for all other checks besides the infra checks, you can:
|
||||
|
||||
```
|
||||
$ trivy k8s cluster --report summary --components=workload --security-checks=config # scan all components besides infra
|
||||
$ trivy k8s cluster --report summary --components=workload --scanners=config # scan all components besides infra
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ License checking classifies the identified licenses and map the classification t
|
||||
This section shows how to scan license in container image and filesystem.
|
||||
|
||||
### Standard scanning
|
||||
Specify an image name with `--security-checks license`.
|
||||
Specify an image name with `--scanners license`.
|
||||
|
||||
``` shell
|
||||
$ trivy image --security-checks license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15
|
||||
$ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15
|
||||
2022-07-13T17:28:39.526+0300 INFO License scanning is enabled
|
||||
|
||||
OS Packages (license)
|
||||
@@ -78,7 +78,7 @@ Total: 6 (UNKNOWN: 0, HIGH: 6, CRITICAL: 0)
|
||||
Specify `--license-full`
|
||||
|
||||
``` shell
|
||||
$ trivy image --security-checks license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana
|
||||
$ trivy image --scanners license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana
|
||||
2022-07-13T17:48:40.905+0300 INFO Full license scanning is enabled
|
||||
|
||||
OS Packages (license)
|
||||
@@ -141,7 +141,7 @@ Trivy has number of configuration flags for use with license scanning;
|
||||
Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the `--ignored-licenses` flag;
|
||||
|
||||
```shell
|
||||
$ trivy image --security-checks license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest
|
||||
$ trivy image --scanners license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest
|
||||
2022-07-13T18:15:28.605Z INFO License scanning is enabled
|
||||
|
||||
OS Packages (license)
|
||||
|
||||
@@ -37,28 +37,28 @@ $ trivy config [YOUR_IaC_DIRECTORY]
|
||||
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
You can also enable misconfiguration detection in container image, filesystem and git repository scanning via `--security-checks config`.
|
||||
You can also enable misconfiguration detection in container image, filesystem and git repository scanning via `--scanners config`.
|
||||
|
||||
```bash
|
||||
$ trivy image --security-checks config IMAGE_NAME
|
||||
$ trivy image --scanners config IMAGE_NAME
|
||||
```
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks config /path/to/dir
|
||||
$ trivy fs --scanners config /path/to/dir
|
||||
```
|
||||
|
||||
!!! note
|
||||
Misconfiguration detection is not enabled by default in `image`, `fs` and `repo` subcommands.
|
||||
|
||||
Unlike the `config` subcommand, `image`, `fs` and `repo` subcommands can also scan for vulnerabilities and secrets at the same time.
|
||||
You can specify `--security-checks vuln,config,secret` to enable vulnerability and secret detection as well as misconfiguration detection.
|
||||
You can specify `--scanners vuln,config,secret` to enable vulnerability and secret detection as well as misconfiguration detection.
|
||||
|
||||
|
||||
!!! example
|
||||
``` bash
|
||||
$ ls myapp/
|
||||
Dockerfile Pipfile.lock
|
||||
$ trivy fs --security-checks vuln,config,secret --severity HIGH,CRITICAL myapp/
|
||||
$ trivy fs --scanners vuln,config,secret --severity HIGH,CRITICAL myapp/
|
||||
2022-05-16T13:42:21.440+0100 INFO Number of language-specific files: 1
|
||||
2022-05-16T13:42:21.440+0100 INFO Detecting pipenv vulnerabilities...
|
||||
2022-05-16T13:42:21.440+0100 INFO Detected config files: 1
|
||||
|
||||
@@ -9,7 +9,7 @@ Aliases:
|
||||
|
||||
Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--scanners string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
@@ -47,8 +47,8 @@ Vulnerability Flags
|
||||
Misconfiguration Flags
|
||||
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
|
||||
--config-policy strings specify paths to the Rego policy files directory, applying config files
|
||||
--file-patterns strings specify config file patterns, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--file-patterns strings specify config file patterns, available with '--scanners config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--policy-namespaces strings Rego namespaces
|
||||
--trace enable more verbose trace output for custom queries
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ Cache Flags
|
||||
Misconfiguration Flags
|
||||
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
|
||||
--config-policy strings specify paths to the Rego policy files directory, applying config files
|
||||
--file-patterns strings specify config file patterns, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--file-patterns strings specify config file patterns, available with '--scanners config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--policy-namespaces strings Rego namespaces
|
||||
--trace enable more verbose trace output for custom queries
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Examples:
|
||||
|
||||
Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--scanners string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
@@ -55,8 +55,8 @@ Vulnerability Flags
|
||||
Misconfiguration Flags
|
||||
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
|
||||
--config-policy strings specify paths to the Rego policy files directory, applying config files
|
||||
--file-patterns strings specify config file patterns, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--file-patterns strings specify config file patterns, available with '--scanners config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--policy-namespaces strings Rego namespaces
|
||||
--trace enable more verbose trace output for custom queries
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Examples:
|
||||
|
||||
Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--scanners string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
@@ -73,8 +73,8 @@ Vulnerability Flags
|
||||
Misconfiguration Flags
|
||||
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
|
||||
--config-policy strings specify paths to the Rego policy files directory, applying config files
|
||||
--file-patterns strings specify config file patterns, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--file-patterns strings specify config file patterns, available with '--scanners config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--policy-namespaces strings Rego namespaces
|
||||
--trace enable more verbose trace output for custom queries
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Examples:
|
||||
|
||||
Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--scanners string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
@@ -52,8 +52,8 @@ Vulnerability Flags
|
||||
Misconfiguration Flags
|
||||
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
|
||||
--config-policy strings specify paths to the Rego policy files directory, applying config files
|
||||
--file-patterns strings specify config file patterns, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--file-patterns strings specify config file patterns, available with '--scanners config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--policy-namespaces strings Rego namespaces
|
||||
--trace enable more verbose trace output for custom queries
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--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 (rekor)
|
||||
--security-checks strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
|
||||
--scanners strings comma-separated list of what security issues to detect (vuln,config,secret,license) (default [vuln,secret])
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
@@ -60,7 +60,7 @@ Misconfiguration Flags
|
||||
--helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
|
||||
--helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
|
||||
--helm-values strings specify paths to override the Helm values.yaml files
|
||||
--include-non-failures include successes and exceptions, available with '--security-checks config'
|
||||
--include-non-failures include successes and exceptions, available with '--scanners config'
|
||||
--tf-vars strings specify paths to override the Terraform tfvars files
|
||||
|
||||
Secret Flags
|
||||
|
||||
@@ -19,7 +19,7 @@ Examples:
|
||||
|
||||
Scan Flags
|
||||
--offline-scan do not issue API requests to identify dependencies
|
||||
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--scanners string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
|
||||
--skip-dirs strings specify the directories where the traversal is skipped
|
||||
--skip-files strings specify the file paths to skip traversal
|
||||
|
||||
|
||||
@@ -102,9 +102,9 @@ scan:
|
||||
# Default is false
|
||||
offline-scan: false
|
||||
|
||||
# Same as '--security-checks'
|
||||
# Same as '--scanners'
|
||||
# Default depends on subcommand
|
||||
security-checks:
|
||||
scanners:
|
||||
- vuln
|
||||
- config
|
||||
- secret
|
||||
|
||||
@@ -15,7 +15,7 @@ By default, `--format cyclonedx` represents SBOM and doesn't include vulnerabili
|
||||
|
||||
```
|
||||
$ trivy image --format cyclonedx --output result.json alpine:3.15
|
||||
2022-07-19T07:47:27.624Z INFO "--format cyclonedx" disables security checks. Specify "--security-checks vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.
|
||||
2022-07-19T07:47:27.624Z INFO "--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.
|
||||
```
|
||||
|
||||
<details>
|
||||
@@ -239,10 +239,10 @@ $ cat result.json | jq .
|
||||
|
||||
</details>
|
||||
|
||||
If you want to include vulnerabilities, you can enable vulnerability scanning via `--security-checks vuln`.
|
||||
If you want to include vulnerabilities, you can enable vulnerability scanning via `--scanners vuln`.
|
||||
|
||||
```
|
||||
$ trivy image --security-checks vuln --format cyclonedx --output result.json alpine:3.15
|
||||
$ trivy image --scanners vuln --format cyclonedx --output result.json alpine:3.15
|
||||
```
|
||||
|
||||
## Scanning
|
||||
|
||||
@@ -48,10 +48,10 @@ aws-account-id
|
||||
```
|
||||
|
||||
## Disable secret scanning
|
||||
If you need vulnerability scanning only, you can disable secret scanning via the `--security-checks` flag.
|
||||
If you need vulnerability scanning only, you can disable secret scanning via the `--scanners` flag.
|
||||
|
||||
``` shell
|
||||
$ trivy image --security-checks vuln alpine:3.15
|
||||
$ trivy image --scanners vuln alpine:3.15
|
||||
```
|
||||
|
||||
## With configuration file
|
||||
|
||||
@@ -106,10 +106,10 @@ All rules are disabled except for the ones you specify, so it runs very fast.
|
||||
On the other hand, you should use `disable-rules` if you just want to disable some built-in rules.
|
||||
See the [enable-rules][enable-rules] and [disable-rules][disable-rules] sections for the detail.
|
||||
|
||||
If you don't need secret scanning, you can disable it via the `--security-checks` flag.
|
||||
If you don't need secret scanning, you can disable it via the `--scanners` flag.
|
||||
|
||||
```shell
|
||||
$ trivy image --security-checks vuln alpine:3.15
|
||||
$ trivy image --scanners vuln alpine:3.15
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ $ trivy vm ami:${your_ami_id}
|
||||
### Example
|
||||
|
||||
```shell
|
||||
$ trivy vm --security-checks vuln ami:ami-0123456789abcdefg
|
||||
$ trivy vm --scanners vuln ami:ami-0123456789abcdefg
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The scanning could be faster if you enable only vulnerability scanning (`--security-checks vuln`) because Trivy tries to download only necessary blocks for vulnerability detection.
|
||||
The scanning could be faster if you enable only vulnerability scanning (`--scanners vuln`) because Trivy tries to download only necessary blocks for vulnerability detection.
|
||||
|
||||
If you want to scan a AMI of non-default setting region, you can set any region via `--aws-region` option.
|
||||
|
||||
@@ -52,11 +52,11 @@ $ trivy vm ebs:${your_ebs_snapshot_id}
|
||||
|
||||
### Example
|
||||
```shell
|
||||
$ trivy vm --security-checks vuln ebs:snap-0123456789abcdefg
|
||||
$ trivy vm --scanners vuln ebs:snap-0123456789abcdefg
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The scanning could be faster if you enable only vulnerability scanning (`--security-checks vuln`) because Trivy tries to download only necessary blocks for vulnerability detection.
|
||||
The scanning could be faster if you enable only vulnerability scanning (`--scanners vuln`) because Trivy tries to download only necessary blocks for vulnerability detection.
|
||||
|
||||
If you want to scan an EBS Snapshot of non-default setting region, you can set any region via `--aws-region` option.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ To scan VM images, you can use the `vm` subcommand.
|
||||
Pass the path to your local VM image file.
|
||||
|
||||
```bash
|
||||
$ trivy vm --security-checks vuln disk.vmdk
|
||||
$ trivy vm --scanners vuln disk.vmdk
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
@@ -40,7 +40,7 @@ The following table provides an outline of the features Trivy offers.
|
||||
33.25 MiB / 33.25 MiB [------------------------------] 100.00% 4.20 MiB p/s 8.1s
|
||||
2022-07-27T09:30:21.756Z INFO Vulnerability scanning is enabled
|
||||
2022-07-27T09:30:21.756Z INFO Secret scanning is enabled
|
||||
2022-07-27T09:30:21.756Z INFO If your scanning is slow, please try '--security-checks vuln' to disable secret scanning
|
||||
2022-07-27T09:30:21.756Z INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning
|
||||
2022-07-27T09:30:21.756Z INFO Please see also https://aquasecurity.github.io/trivy/v0.30.4/docs/secret/scanning/#recommendation for faster secret detection
|
||||
2022-07-27T09:30:22.205Z INFO Detected OS: cbl-mariner
|
||||
2022-07-27T09:30:22.205Z INFO Detecting CBL-Mariner vulnerabilities...
|
||||
|
||||
@@ -37,7 +37,7 @@ $ trivy image --platform=linux/arm alpine:3.16.1
|
||||
```
|
||||
2022-10-25T21:00:50.972+0300 INFO Vulnerability scanning is enabled
|
||||
2022-10-25T21:00:50.972+0300 INFO Secret scanning is enabled
|
||||
2022-10-25T21:00:50.972+0300 INFO If your scanning is slow, please try '--security-checks vuln' to disable secret scanning
|
||||
2022-10-25T21:00:50.972+0300 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning
|
||||
2022-10-25T21:00:50.972+0300 INFO Please see also https://aquasecurity.github.io/trivy/dev/docs/secret/scanning/#recommendation for faster secret detection
|
||||
2022-10-25T21:00:56.190+0300 INFO Detected OS: alpine
|
||||
2022-10-25T21:00:56.190+0300 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
@@ -58,7 +58,7 @@ Trivy is integrated with many popular platforms and applications. The complete l
|
||||
### General usage
|
||||
|
||||
```bash
|
||||
trivy <target> [--security-checks <scanner1,scanner2>] <subject>
|
||||
trivy <target> [--scanners <scanner1,scanner2>] <subject>
|
||||
```
|
||||
|
||||
Examples:
|
||||
@@ -80,7 +80,7 @@ trivy image python:3.4-alpine
|
||||
</details>
|
||||
|
||||
```bash
|
||||
trivy fs --security-checks vuln,secret,config myproject/
|
||||
trivy fs --scanners vuln,secret,config myproject/
|
||||
```
|
||||
|
||||
<details>
|
||||
|
||||
@@ -150,7 +150,7 @@ trivy:
|
||||
# Image report
|
||||
- ./trivy image --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate-image.json $IMAGE
|
||||
# Filesystem report
|
||||
- ./trivy filesystem --security-checks config,vuln --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate-fs.json .
|
||||
- ./trivy filesystem --scanners config,vuln --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate-fs.json .
|
||||
# Combine report
|
||||
- apk update && apk add jq
|
||||
- jq -s 'add' gl-codeclimate-image.json gl-codeclimate-fs.json > gl-codeclimate.json
|
||||
|
||||
@@ -14,7 +14,7 @@ scan:
|
||||
- /usr/lib
|
||||
- /usr/include
|
||||
|
||||
security-checks:
|
||||
scanners:
|
||||
- vuln
|
||||
- secret
|
||||
vulnerability:
|
||||
|
||||
@@ -11,11 +11,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
func TestFilesystem(t *testing.T) {
|
||||
type args struct {
|
||||
securityChecks string
|
||||
scanners string
|
||||
severity []string
|
||||
ignoreIDs []string
|
||||
policyPaths []string
|
||||
@@ -39,7 +41,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "gomod",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/gomod",
|
||||
},
|
||||
golden: "testdata/gomod.json.golden",
|
||||
@@ -47,7 +49,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "gomod with skip files",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/gomod",
|
||||
skipFiles: []string{"testdata/fixtures/fs/gomod/submod2/go.mod"},
|
||||
},
|
||||
@@ -56,7 +58,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "gomod with skip dirs",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/gomod",
|
||||
skipDirs: []string{"testdata/fixtures/fs/gomod/submod2"},
|
||||
},
|
||||
@@ -65,7 +67,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "nodejs",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/nodejs",
|
||||
listAllPkgs: true,
|
||||
},
|
||||
@@ -74,7 +76,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "yarn",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/yarn",
|
||||
listAllPkgs: true,
|
||||
},
|
||||
@@ -83,7 +85,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "pnpm",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/pnpm",
|
||||
},
|
||||
golden: "testdata/pnpm.json.golden",
|
||||
@@ -91,7 +93,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "pip",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/pip",
|
||||
},
|
||||
@@ -100,7 +102,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "pom",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/pom",
|
||||
},
|
||||
golden: "testdata/pom.json.golden",
|
||||
@@ -108,7 +110,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "gradle",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
input: "testdata/fixtures/fs/gradle",
|
||||
},
|
||||
golden: "testdata/gradle.json.golden",
|
||||
@@ -116,7 +118,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "conan",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/conan",
|
||||
},
|
||||
@@ -125,7 +127,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "nuget",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/nuget",
|
||||
},
|
||||
@@ -134,7 +136,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dotnet",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/dotnet",
|
||||
},
|
||||
@@ -143,7 +145,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "cocoapods",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/cocoapods",
|
||||
},
|
||||
@@ -152,7 +154,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "pubspec.lock",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/pubspec",
|
||||
},
|
||||
@@ -161,7 +163,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "mix.lock",
|
||||
args: args{
|
||||
securityChecks: "vuln",
|
||||
scanners: types.VulnerabilityScanner,
|
||||
listAllPkgs: true,
|
||||
input: "testdata/fixtures/fs/mixlock",
|
||||
},
|
||||
@@ -170,7 +172,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dockerfile",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/dockerfile",
|
||||
namespaces: []string{"testing"},
|
||||
},
|
||||
@@ -179,7 +181,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dockerfile with custom file pattern",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/dockerfile_file_pattern",
|
||||
namespaces: []string{"testing"},
|
||||
filePatterns: []string{"dockerfile:Customfile"},
|
||||
@@ -189,7 +191,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dockerfile with rule exception",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
policyPaths: []string{"testdata/fixtures/fs/rule-exception/policy"},
|
||||
input: "testdata/fixtures/fs/rule-exception",
|
||||
},
|
||||
@@ -198,7 +200,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dockerfile with namespace exception",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
policyPaths: []string{"testdata/fixtures/fs/namespace-exception/policy"},
|
||||
input: "testdata/fixtures/fs/namespace-exception",
|
||||
},
|
||||
@@ -207,7 +209,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "dockerfile with custom policies",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
policyPaths: []string{"testdata/fixtures/fs/custom-policy/policy"},
|
||||
namespaces: []string{"user"},
|
||||
input: "testdata/fixtures/fs/custom-policy",
|
||||
@@ -217,7 +219,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "tarball helm chart scanning with builtin policies",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/helm",
|
||||
},
|
||||
golden: "testdata/helm.json.golden",
|
||||
@@ -225,7 +227,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "helm chart directory scanning with builtin policies",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/helm_testchart",
|
||||
},
|
||||
golden: "testdata/helm_testchart.json.golden",
|
||||
@@ -233,7 +235,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "helm chart directory scanning with value overrides using set",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/helm_testchart",
|
||||
helmSet: []string{"securityContext.runAsUser=0"},
|
||||
},
|
||||
@@ -242,7 +244,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "helm chart directory scanning with value overrides using value file",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/helm_testchart",
|
||||
helmValuesFile: []string{"testdata/fixtures/fs/helm_values/values.yaml"},
|
||||
},
|
||||
@@ -251,7 +253,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "helm chart directory scanning with builtin policies and non string Chart name",
|
||||
args: args{
|
||||
securityChecks: "config",
|
||||
scanners: types.MisconfigScanner,
|
||||
input: "testdata/fixtures/fs/helm_badname",
|
||||
},
|
||||
golden: "testdata/helm_badname.json.golden",
|
||||
@@ -259,7 +261,7 @@ func TestFilesystem(t *testing.T) {
|
||||
{
|
||||
name: "secrets",
|
||||
args: args{
|
||||
securityChecks: "vuln,secret",
|
||||
scanners: "vuln,secret",
|
||||
input: "testdata/fixtures/fs/secrets",
|
||||
secretConfig: "testdata/fixtures/fs/secrets/trivy-secret.yaml",
|
||||
},
|
||||
@@ -305,12 +307,19 @@ func TestFilesystem(t *testing.T) {
|
||||
}
|
||||
|
||||
osArgs := []string{
|
||||
"-q", "--cache-dir", cacheDir, command, "--skip-db-update", "--skip-policy-update",
|
||||
"--format", format, "--offline-scan",
|
||||
"-q",
|
||||
"--cache-dir",
|
||||
cacheDir,
|
||||
command,
|
||||
"--skip-db-update",
|
||||
"--skip-policy-update",
|
||||
"--format",
|
||||
format,
|
||||
"--offline-scan",
|
||||
}
|
||||
|
||||
if tt.args.securityChecks != "" {
|
||||
osArgs = append(osArgs, "--security-checks", tt.args.securityChecks)
|
||||
if tt.args.scanners != "" {
|
||||
osArgs = append(osArgs, "--scanners", tt.args.scanners)
|
||||
}
|
||||
|
||||
if len(tt.args.policyPaths) != 0 {
|
||||
|
||||
@@ -75,8 +75,15 @@ func TestVM(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
osArgs := []string{
|
||||
"--cache-dir", cacheDir, "vm", "--security-checks", "vuln", "-q", "--skip-db-update",
|
||||
"--format", tt.args.format,
|
||||
"--cache-dir",
|
||||
cacheDir,
|
||||
"vm",
|
||||
"--scanners",
|
||||
"vuln",
|
||||
"-q",
|
||||
"--skip-db-update",
|
||||
"--format",
|
||||
tt.args.format,
|
||||
}
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
@@ -581,7 +581,7 @@ func NewConfigCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
options.DisabledAnalyzers = append(analyzer.TypeOSes, analyzer.TypeLanguages...)
|
||||
|
||||
// Scan only for misconfigurations
|
||||
options.SecurityChecks = []string{types.SecurityCheckConfig}
|
||||
options.Scanners = []string{types.MisconfigScanner}
|
||||
|
||||
return artifact.Run(cmd.Context(), options, artifact.TargetFilesystem)
|
||||
},
|
||||
@@ -743,15 +743,15 @@ func NewModuleCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
|
||||
func NewKubernetesCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
scanFlags := flag.NewScanFlagGroup()
|
||||
securityChecks := flag.SecurityChecksFlag
|
||||
securityChecks.Value = fmt.Sprintf( // overwrite the default value
|
||||
scanners := flag.ScannersFlag
|
||||
scanners.Value = fmt.Sprintf( // overwrite the default value
|
||||
"%s,%s,%s,%s",
|
||||
types.SecurityCheckVulnerability,
|
||||
types.SecurityCheckConfig,
|
||||
types.SecurityCheckSecret,
|
||||
types.SecurityCheckRbac,
|
||||
types.VulnerabilityScanner,
|
||||
types.MisconfigScanner,
|
||||
types.SecretScanner,
|
||||
types.RBACScanner,
|
||||
)
|
||||
scanFlags.SecurityChecks = &securityChecks
|
||||
scanFlags.Scanners = &scanners
|
||||
|
||||
reportFlagGroup := flag.NewReportFlagGroup()
|
||||
compliance := flag.ComplianceFlag
|
||||
@@ -908,7 +908,7 @@ func NewVMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
Aliases: []string{},
|
||||
Short: "[EXPERIMENTAL] Scan a virtual machine image",
|
||||
Example: ` # Scan your AWS AMI
|
||||
$ trivy vm --security-checks vuln ami:${your_ami_id}
|
||||
$ trivy vm --scanners vuln ami:${your_ami_id}
|
||||
|
||||
# Scan your AWS EBS snapshot
|
||||
$ trivy vm ebs:${your_ebs_snapshot_id}
|
||||
@@ -949,7 +949,7 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
reportFlagGroup.ReportFormat = nil // TODO: support --report summary
|
||||
|
||||
scanFlags := flag.NewScanFlagGroup()
|
||||
scanFlags.SecurityChecks = nil // disable '--security-checks' as it always scans for vulnerabilities
|
||||
scanFlags.Scanners = nil // disable '--scanners' as it always scans for vulnerabilities
|
||||
|
||||
sbomFlags := &flag.Flags{
|
||||
CacheFlagGroup: flag.NewCacheFlagGroup(),
|
||||
@@ -989,7 +989,7 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||
}
|
||||
|
||||
// Scan vulnerabilities
|
||||
options.SecurityChecks = []string{types.SecurityCheckVulnerability}
|
||||
options.Scanners = []string{types.VulnerabilityScanner}
|
||||
|
||||
return artifact.Run(cmd.Context(), options, artifact.TargetSBOM)
|
||||
},
|
||||
|
||||
@@ -46,7 +46,11 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultPolicyNamespaces = []string{"appshield", "defsec", "builtin"}
|
||||
defaultPolicyNamespaces = []string{
|
||||
"appshield",
|
||||
"defsec",
|
||||
"builtin",
|
||||
}
|
||||
SkipScan = errors.New("skip subsequent processes")
|
||||
)
|
||||
|
||||
@@ -293,7 +297,7 @@ func (r *runner) Report(opts flag.Options, report types.Report) error {
|
||||
|
||||
func (r *runner) initDB(opts flag.Options) error {
|
||||
// When scanning config files or running as client mode, it doesn't need to download the vulnerability database.
|
||||
if opts.ServerAddr != "" || !slices.Contains(opts.SecurityChecks, types.SecurityCheckVulnerability) {
|
||||
if opts.ServerAddr != "" || !slices.Contains(opts.Scanners, types.VulnerabilityScanner) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -448,19 +452,19 @@ func disabledAnalyzers(opts flag.Options) []analyzer.Type {
|
||||
}
|
||||
|
||||
// Do not perform secret scanning when it is not specified.
|
||||
if !slices.Contains(opts.SecurityChecks, types.SecurityCheckSecret) {
|
||||
if !slices.Contains(opts.Scanners, types.SecretScanner) {
|
||||
analyzers = append(analyzers, analyzer.TypeSecret)
|
||||
}
|
||||
|
||||
// Do not perform misconfiguration scanning when it is not specified.
|
||||
if !slices.Contains(opts.SecurityChecks, types.SecurityCheckConfig) &&
|
||||
!slices.Contains(opts.SecurityChecks, types.SecurityCheckRbac) {
|
||||
if !slices.Contains(opts.Scanners, types.MisconfigScanner) &&
|
||||
!slices.Contains(opts.Scanners, types.RBACScanner) {
|
||||
analyzers = append(analyzers, analyzer.TypeConfigFiles...)
|
||||
}
|
||||
|
||||
// Scanning file headers and license files is expensive.
|
||||
// It is performed only when '--security-checks license' and '--license-full' are specified.
|
||||
if !slices.Contains(opts.SecurityChecks, types.SecurityCheckLicense) || !opts.LicenseFull {
|
||||
// It is performed only when '--scanners license' and '--license-full' are specified.
|
||||
if !slices.Contains(opts.Scanners, types.LicenseScanner) || !opts.LicenseFull {
|
||||
analyzers = append(analyzers, analyzer.TypeLicenseFile)
|
||||
}
|
||||
|
||||
@@ -479,7 +483,7 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
||||
|
||||
scanOptions := types.ScanOptions{
|
||||
VulnType: opts.VulnType,
|
||||
SecurityChecks: opts.SecurityChecks,
|
||||
Scanners: opts.Scanners,
|
||||
ScanRemovedPackages: opts.ScanRemovedPkgs, // this is valid only for 'image' subcommand
|
||||
Platform: opts.Platform, // this is valid only for 'image' subcommand
|
||||
ListAllPackages: opts.ListAllPkgs,
|
||||
@@ -487,7 +491,7 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
||||
FilePatterns: opts.FilePatterns,
|
||||
}
|
||||
|
||||
if slices.Contains(opts.SecurityChecks, types.SecurityCheckVulnerability) {
|
||||
if slices.Contains(opts.Scanners, types.VulnerabilityScanner) {
|
||||
log.Logger.Info("Vulnerability scanning is enabled")
|
||||
log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType)
|
||||
}
|
||||
@@ -506,7 +510,7 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
||||
|
||||
// ScannerOption is filled only when config scanning is enabled.
|
||||
var configScannerOptions config.ScannerOption
|
||||
if slices.Contains(opts.SecurityChecks, types.SecurityCheckConfig) {
|
||||
if slices.Contains(opts.Scanners, types.MisconfigScanner) {
|
||||
log.Logger.Info("Misconfiguration scanning is enabled")
|
||||
configScannerOptions = config.ScannerOption{
|
||||
Trace: opts.Trace,
|
||||
@@ -523,16 +527,16 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
||||
}
|
||||
|
||||
// Do not load config file for secret scanning
|
||||
if slices.Contains(opts.SecurityChecks, types.SecurityCheckSecret) {
|
||||
if slices.Contains(opts.Scanners, types.SecretScanner) {
|
||||
ver := canonicalVersion(opts.AppVersion)
|
||||
log.Logger.Info("Secret scanning is enabled")
|
||||
log.Logger.Info("If your scanning is slow, please try '--security-checks vuln' to disable secret scanning")
|
||||
log.Logger.Info("If your scanning is slow, please try '--scanners vuln' to disable secret scanning")
|
||||
log.Logger.Infof("Please see also https://aquasecurity.github.io/trivy/%s/docs/secret/scanning/#recommendation for faster secret detection", ver)
|
||||
} else {
|
||||
opts.SecretConfigPath = ""
|
||||
}
|
||||
|
||||
if slices.Contains(opts.SecurityChecks, types.SecurityCheckLicense) {
|
||||
if slices.Contains(opts.Scanners, types.LicenseScanner) {
|
||||
if opts.LicenseFull {
|
||||
log.Logger.Info("Full license scanning is enabled")
|
||||
} else {
|
||||
|
||||
@@ -61,13 +61,13 @@ const (
|
||||
WarnStatus ControlStatus = "WARN"
|
||||
)
|
||||
|
||||
// SecurityChecks reads spec control and determines the scanners by check ID prefix
|
||||
func (cs *ComplianceSpec) SecurityChecks() ([]types.SecurityCheck, error) {
|
||||
scannerTypes := map[types.SecurityCheck]struct{}{}
|
||||
// Scanners reads spec control and determines the scanners by check ID prefix
|
||||
func (cs *ComplianceSpec) Scanners() ([]types.Scanner, error) {
|
||||
scannerTypes := map[types.Scanner]struct{}{}
|
||||
for _, control := range cs.Spec.Controls {
|
||||
for _, check := range control.Checks {
|
||||
scannerType := securityCheckByCheckID(check.ID)
|
||||
if scannerType == types.SecurityCheckUnknown {
|
||||
scannerType := scannerByCheckID(check.ID)
|
||||
if scannerType == types.ScannerUnknown {
|
||||
return nil, xerrors.Errorf("unsupported check ID: %s", check.ID)
|
||||
}
|
||||
scannerTypes[scannerType] = struct{}{}
|
||||
@@ -77,26 +77,26 @@ func (cs *ComplianceSpec) SecurityChecks() ([]types.SecurityCheck, error) {
|
||||
}
|
||||
|
||||
// CheckIDs return list of compliance check IDs
|
||||
func (cs *ComplianceSpec) CheckIDs() map[types.SecurityCheck][]string {
|
||||
checkIDsMap := map[types.SecurityCheck][]string{}
|
||||
func (cs *ComplianceSpec) CheckIDs() map[types.Scanner][]string {
|
||||
checkIDsMap := map[types.Scanner][]string{}
|
||||
for _, control := range cs.Spec.Controls {
|
||||
for _, check := range control.Checks {
|
||||
scannerType := securityCheckByCheckID(check.ID)
|
||||
scannerType := scannerByCheckID(check.ID)
|
||||
checkIDsMap[scannerType] = append(checkIDsMap[scannerType], check.ID)
|
||||
}
|
||||
}
|
||||
return checkIDsMap
|
||||
}
|
||||
|
||||
func securityCheckByCheckID(checkID string) types.SecurityCheck {
|
||||
func scannerByCheckID(checkID string) types.Scanner {
|
||||
checkID = strings.ToLower(checkID)
|
||||
switch {
|
||||
case strings.HasPrefix(checkID, "cve-") || strings.HasPrefix(checkID, "dla-"):
|
||||
return types.SecurityCheckVulnerability
|
||||
return types.VulnerabilityScanner
|
||||
case strings.HasPrefix(checkID, "avd-"):
|
||||
return types.SecurityCheckConfig
|
||||
return types.MisconfigScanner
|
||||
default:
|
||||
return types.SecurityCheckUnknown
|
||||
return types.ScannerUnknown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
)
|
||||
|
||||
func TestComplianceSpec_SecurityChecks(t *testing.T) {
|
||||
func TestComplianceSpec_Scanners(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
spec spec.Spec
|
||||
want []types.SecurityCheck
|
||||
want []types.Scanner
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
@@ -48,7 +48,7 @@ func TestComplianceSpec_SecurityChecks(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []types.SecurityCheck{types.SecurityCheckConfig},
|
||||
want: []types.Scanner{types.MisconfigScanner},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
@@ -89,7 +89,10 @@ func TestComplianceSpec_SecurityChecks(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []types.SecurityCheck{types.SecurityCheckConfig, types.SecurityCheckVulnerability},
|
||||
want: []types.Scanner{
|
||||
types.MisconfigScanner,
|
||||
types.VulnerabilityScanner,
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
@@ -120,12 +123,12 @@ func TestComplianceSpec_SecurityChecks(t *testing.T) {
|
||||
cs := &spec.ComplianceSpec{
|
||||
Spec: tt.spec,
|
||||
}
|
||||
got, err := cs.SecurityChecks()
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("SecurityChecks()")) {
|
||||
got, err := cs.Scanners()
|
||||
if !tt.wantErr(t, err, fmt.Sprintf("Scanners()")) {
|
||||
return
|
||||
}
|
||||
sort.Strings(got) // for consistency
|
||||
assert.Equalf(t, tt.want, got, "SecurityChecks()")
|
||||
assert.Equalf(t, tt.want, got, "Scanners()")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -134,7 +137,7 @@ func TestComplianceSpec_CheckIDs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
spec spec.Spec
|
||||
want map[types.SecurityCheck][]string
|
||||
want map[types.Scanner][]string
|
||||
}{
|
||||
{
|
||||
name: "get config scanner type by check id prefix",
|
||||
@@ -166,8 +169,8 @@ func TestComplianceSpec_CheckIDs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: map[types.SecurityCheck][]string{
|
||||
types.SecurityCheckConfig: {
|
||||
want: map[types.Scanner][]string{
|
||||
types.MisconfigScanner: {
|
||||
"AVD-KSV012",
|
||||
"AVD-1.2.31",
|
||||
"AVD-1.2.32",
|
||||
@@ -212,13 +215,13 @@ func TestComplianceSpec_CheckIDs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: map[types.SecurityCheck][]string{
|
||||
types.SecurityCheckConfig: {
|
||||
want: map[types.Scanner][]string{
|
||||
types.MisconfigScanner: {
|
||||
"AVD-KSV012",
|
||||
"AVD-1.2.31",
|
||||
"AVD-1.2.32",
|
||||
},
|
||||
types.SecurityCheckVulnerability: {
|
||||
types.VulnerabilityScanner: {
|
||||
"CVE-9999-9999",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
)
|
||||
|
||||
// MapSpecCheckIDToFilteredResults map spec check id to filtered scan results
|
||||
func MapSpecCheckIDToFilteredResults(result types.Result, checkIDs map[types.SecurityCheck][]string) map[string]types.Results {
|
||||
func MapSpecCheckIDToFilteredResults(result types.Result, checkIDs map[types.Scanner][]string) map[string]types.Results {
|
||||
mapCheckByID := make(map[string]types.Results)
|
||||
for _, vuln := range result.Vulnerabilities {
|
||||
// Skip irrelevant check IDs
|
||||
if !slices.Contains(checkIDs[types.SecurityCheckVulnerability], vuln.GetID()) {
|
||||
if !slices.Contains(checkIDs[types.VulnerabilityScanner], vuln.GetID()) {
|
||||
continue
|
||||
}
|
||||
mapCheckByID[vuln.GetID()] = append(mapCheckByID[vuln.GetID()], types.Result{
|
||||
@@ -23,7 +23,7 @@ func MapSpecCheckIDToFilteredResults(result types.Result, checkIDs map[types.Sec
|
||||
}
|
||||
for _, m := range result.Misconfigurations {
|
||||
// Skip irrelevant check IDs
|
||||
if !slices.Contains(checkIDs[types.SecurityCheckConfig], m.GetID()) {
|
||||
if !slices.Contains(checkIDs[types.MisconfigScanner], m.GetID()) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -11,19 +11,19 @@ import (
|
||||
)
|
||||
|
||||
func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
|
||||
checkIDs := map[types.SecurityCheck][]string{
|
||||
types.SecurityCheckConfig: {
|
||||
checkIDs := map[types.Scanner][]string{
|
||||
types.MisconfigScanner: {
|
||||
"AVD-KSV012",
|
||||
"AVD-1.2.31",
|
||||
"AVD-1.2.32",
|
||||
},
|
||||
types.SecurityCheckVulnerability: {
|
||||
types.VulnerabilityScanner: {
|
||||
"CVE-9999-9999",
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
checkIDs map[types.SecurityCheck][]string
|
||||
checkIDs map[types.Scanner][]string
|
||||
result types.Result
|
||||
want map[string]types.Results
|
||||
}{
|
||||
@@ -35,9 +35,18 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
|
||||
Class: types.ClassConfig,
|
||||
Type: ftypes.Kubernetes,
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{AVDID: "AVD-KSV012", Status: types.StatusFailure},
|
||||
{AVDID: "AVD-KSV013", Status: types.StatusFailure},
|
||||
{AVDID: "AVD-1.2.31", Status: types.StatusFailure},
|
||||
{
|
||||
AVDID: "AVD-KSV012",
|
||||
Status: types.StatusFailure,
|
||||
},
|
||||
{
|
||||
AVDID: "AVD-KSV013",
|
||||
Status: types.StatusFailure,
|
||||
},
|
||||
{
|
||||
AVDID: "AVD-1.2.31",
|
||||
Status: types.StatusFailure,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: map[string]types.Results{
|
||||
@@ -46,9 +55,16 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
|
||||
Target: "target",
|
||||
Class: types.ClassConfig,
|
||||
Type: ftypes.Kubernetes,
|
||||
MisconfSummary: &types.MisconfSummary{Successes: 0, Failures: 1, Exceptions: 0},
|
||||
MisconfSummary: &types.MisconfSummary{
|
||||
Successes: 0,
|
||||
Failures: 1,
|
||||
Exceptions: 0,
|
||||
},
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{AVDID: "AVD-KSV012", Status: types.StatusFailure},
|
||||
{
|
||||
AVDID: "AVD-KSV012",
|
||||
Status: types.StatusFailure,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -57,9 +73,16 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
|
||||
Target: "target",
|
||||
Class: types.ClassConfig,
|
||||
Type: ftypes.Kubernetes,
|
||||
MisconfSummary: &types.MisconfSummary{Successes: 0, Failures: 1, Exceptions: 0},
|
||||
MisconfSummary: &types.MisconfSummary{
|
||||
Successes: 0,
|
||||
Failures: 1,
|
||||
Exceptions: 0,
|
||||
},
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{AVDID: "AVD-1.2.31", Status: types.StatusFailure},
|
||||
{
|
||||
AVDID: "AVD-1.2.31",
|
||||
Status: types.StatusFailure,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@ var (
|
||||
Name: "include-non-failures",
|
||||
ConfigName: "misconfiguration.include-non-failures",
|
||||
Value: false,
|
||||
Usage: "include successes and exceptions, available with '--security-checks config'",
|
||||
Usage: "include successes and exceptions, available with '--scanners config'",
|
||||
}
|
||||
HelmValuesFileFlag = Flag{
|
||||
Name: "helm-values",
|
||||
|
||||
@@ -94,14 +94,14 @@ type Options struct {
|
||||
// Align takes consistency of options
|
||||
func (o *Options) Align() {
|
||||
if o.Format == report.FormatSPDX || o.Format == report.FormatSPDXJSON {
|
||||
log.Logger.Info(`"--format spdx" and "--format spdx-json" disable security checks`)
|
||||
o.SecurityChecks = nil
|
||||
log.Logger.Info(`"--format spdx" and "--format spdx-json" disable security scanning`)
|
||||
o.Scanners = nil
|
||||
}
|
||||
|
||||
// Vulnerability scanning is disabled by default for CycloneDX.
|
||||
if o.Format == report.FormatCycloneDX && !viper.IsSet(SecurityChecksFlag.ConfigName) {
|
||||
log.Logger.Info(`"--format cyclonedx" disables security checks. Specify "--security-checks vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.`)
|
||||
o.SecurityChecks = nil
|
||||
if o.Format == report.FormatCycloneDX && !viper.IsSet(ScannersFlag.ConfigName) {
|
||||
log.Logger.Info(`"--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the CycloneDX report.`)
|
||||
o.Scanners = nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +415,8 @@ func flagNameNormalize(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
name = PolicyNamespaceFlag.Name
|
||||
case "ctx":
|
||||
name = ClusterContextFlag.Name
|
||||
case "security-checks":
|
||||
name = ScannersFlag.Name
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
}
|
||||
|
||||
@@ -24,30 +24,42 @@ func Test_getStringSlice(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "happy path. Empty value",
|
||||
flag: &SecurityChecksFlag,
|
||||
flag: &ScannersFlag,
|
||||
flagValue: "",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "happy path. String value",
|
||||
flag: &SecurityChecksFlag,
|
||||
flag: &ScannersFlag,
|
||||
flagValue: "license,vuln",
|
||||
want: []string{types.SecurityCheckLicense, types.SecurityCheckVulnerability},
|
||||
want: []string{
|
||||
types.LicenseScanner,
|
||||
types.VulnerabilityScanner,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path. Slice value",
|
||||
flag: &SecurityChecksFlag,
|
||||
flagValue: []string{"license", "secret"},
|
||||
want: []string{types.SecurityCheckLicense, types.SecurityCheckSecret},
|
||||
flag: &ScannersFlag,
|
||||
flagValue: []string{
|
||||
"license",
|
||||
"secret",
|
||||
},
|
||||
want: []string{
|
||||
types.LicenseScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path. Env value",
|
||||
flag: &SecurityChecksFlag,
|
||||
flag: &ScannersFlag,
|
||||
env: env{
|
||||
key: "TRIVY_SECURITY_CHECKS",
|
||||
value: "rbac,config",
|
||||
},
|
||||
want: []string{types.SecurityCheckRbac, types.SecurityCheckConfig},
|
||||
want: []string{
|
||||
types.RBACScanner,
|
||||
types.MisconfigScanner,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,13 @@ var (
|
||||
Value: false,
|
||||
Usage: "do not issue API requests to identify dependencies",
|
||||
}
|
||||
SecurityChecksFlag = Flag{
|
||||
Name: "security-checks",
|
||||
ConfigName: "scan.security-checks",
|
||||
Value: []string{types.SecurityCheckVulnerability, types.SecurityCheckSecret},
|
||||
ScannersFlag = Flag{
|
||||
Name: "scanners",
|
||||
ConfigName: "scan.scanners",
|
||||
Value: []string{
|
||||
types.VulnerabilityScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
Usage: "comma-separated list of what security issues to detect (vuln,config,secret,license)",
|
||||
}
|
||||
FilePatternsFlag = Flag{
|
||||
@@ -62,7 +65,7 @@ type ScanFlagGroup struct {
|
||||
SkipDirs *Flag
|
||||
SkipFiles *Flag
|
||||
OfflineScan *Flag
|
||||
SecurityChecks *Flag
|
||||
Scanners *Flag
|
||||
FilePatterns *Flag
|
||||
Slow *Flag
|
||||
SBOMSources *Flag
|
||||
@@ -74,7 +77,7 @@ type ScanOptions struct {
|
||||
SkipDirs []string
|
||||
SkipFiles []string
|
||||
OfflineScan bool
|
||||
SecurityChecks []string
|
||||
Scanners []string
|
||||
FilePatterns []string
|
||||
Slow bool
|
||||
SBOMSources []string
|
||||
@@ -86,7 +89,7 @@ func NewScanFlagGroup() *ScanFlagGroup {
|
||||
SkipDirs: &SkipDirsFlag,
|
||||
SkipFiles: &SkipFilesFlag,
|
||||
OfflineScan: &OfflineScanFlag,
|
||||
SecurityChecks: &SecurityChecksFlag,
|
||||
Scanners: &ScannersFlag,
|
||||
FilePatterns: &FilePatternsFlag,
|
||||
Slow: &SlowFlag,
|
||||
SBOMSources: &SBOMSourcesFlag,
|
||||
@@ -99,8 +102,16 @@ func (f *ScanFlagGroup) Name() string {
|
||||
}
|
||||
|
||||
func (f *ScanFlagGroup) Flags() []*Flag {
|
||||
return []*Flag{f.SkipDirs, f.SkipFiles, f.OfflineScan, f.SecurityChecks, f.FilePatterns,
|
||||
f.Slow, f.SBOMSources, f.RekorURL}
|
||||
return []*Flag{
|
||||
f.SkipDirs,
|
||||
f.SkipFiles,
|
||||
f.OfflineScan,
|
||||
f.Scanners,
|
||||
f.FilePatterns,
|
||||
f.Slow,
|
||||
f.SBOMSources,
|
||||
f.RekorURL,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) {
|
||||
@@ -108,9 +119,9 @@ func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) {
|
||||
if len(args) == 1 {
|
||||
target = args[0]
|
||||
}
|
||||
securityChecks, err := parseSecurityCheck(getStringSlice(f.SecurityChecks))
|
||||
scanners, err := parseScanners(getStringSlice(f.Scanners))
|
||||
if err != nil {
|
||||
return ScanOptions{}, xerrors.Errorf("unable to parse security checks: %w", err)
|
||||
return ScanOptions{}, xerrors.Errorf("unable to parse scanners: %w", err)
|
||||
}
|
||||
|
||||
sbomSources := getStringSlice(f.SBOMSources)
|
||||
@@ -123,7 +134,7 @@ func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) {
|
||||
SkipDirs: getStringSlice(f.SkipDirs),
|
||||
SkipFiles: getStringSlice(f.SkipFiles),
|
||||
OfflineScan: getBool(f.OfflineScan),
|
||||
SecurityChecks: securityChecks,
|
||||
Scanners: scanners,
|
||||
FilePatterns: getStringSlice(f.FilePatterns),
|
||||
Slow: getBool(f.Slow),
|
||||
SBOMSources: sbomSources,
|
||||
@@ -131,15 +142,15 @@ func (f *ScanFlagGroup) ToOptions(args []string) (ScanOptions, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func parseSecurityCheck(securityCheck []string) ([]string, error) {
|
||||
var securityChecks []string
|
||||
for _, v := range securityCheck {
|
||||
if !slices.Contains(types.SecurityChecks, v) {
|
||||
return nil, xerrors.Errorf("unknown security check: %s", v)
|
||||
func parseScanners(scanner []string) ([]string, error) {
|
||||
var scanners []string
|
||||
for _, v := range scanner {
|
||||
if !slices.Contains(types.Scanners, v) {
|
||||
return nil, xerrors.Errorf("unknown scanner: %s", v)
|
||||
}
|
||||
securityChecks = append(securityChecks, v)
|
||||
scanners = append(scanners, v)
|
||||
}
|
||||
return securityChecks, nil
|
||||
return scanners, nil
|
||||
}
|
||||
|
||||
func validateSBOMSources(sbomSources []string) error {
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
|
||||
skipDirs []string
|
||||
skipFiles []string
|
||||
offlineScan bool
|
||||
securityChecks string
|
||||
scanners string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -38,22 +38,22 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
|
||||
name: "happy path for configs",
|
||||
args: []string{"alpine:latest"},
|
||||
fields: fields{
|
||||
securityChecks: "config",
|
||||
scanners: "config",
|
||||
},
|
||||
want: flag.ScanOptions{
|
||||
Target: "alpine:latest",
|
||||
SecurityChecks: []string{types.SecurityCheckConfig},
|
||||
Scanners: []string{types.MisconfigScanner},
|
||||
},
|
||||
assertion: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "with wrong security check",
|
||||
name: "with wrong scanner",
|
||||
fields: fields{
|
||||
securityChecks: "vuln,WRONG-CHECK",
|
||||
scanners: "vuln,WRONG-CHECK",
|
||||
},
|
||||
want: flag.ScanOptions{},
|
||||
assertion: func(t require.TestingT, err error, msgs ...interface{}) {
|
||||
require.ErrorContains(t, err, "unknown security check: WRONG-CHECK")
|
||||
require.ErrorContains(t, err, "unknown scanner: WRONG-CHECK")
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -65,7 +65,10 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with two or more targets (args)",
|
||||
args: []string{"alpine:latest", "nginx:latest"},
|
||||
args: []string{
|
||||
"alpine:latest",
|
||||
"nginx:latest",
|
||||
},
|
||||
fields: fields{},
|
||||
want: flag.ScanOptions{},
|
||||
assertion: require.NoError,
|
||||
@@ -73,20 +76,32 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
|
||||
{
|
||||
name: "skip two files",
|
||||
fields: fields{
|
||||
skipFiles: []string{"file1", "file2"},
|
||||
skipFiles: []string{
|
||||
"file1",
|
||||
"file2",
|
||||
},
|
||||
},
|
||||
want: flag.ScanOptions{
|
||||
SkipFiles: []string{"file1", "file2"},
|
||||
SkipFiles: []string{
|
||||
"file1",
|
||||
"file2",
|
||||
},
|
||||
},
|
||||
assertion: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "skip two folders",
|
||||
fields: fields{
|
||||
skipDirs: []string{"dir1", "dir2"},
|
||||
skipDirs: []string{
|
||||
"dir1",
|
||||
"dir2",
|
||||
},
|
||||
},
|
||||
want: flag.ScanOptions{
|
||||
SkipDirs: []string{"dir1", "dir2"},
|
||||
SkipDirs: []string{
|
||||
"dir1",
|
||||
"dir2",
|
||||
},
|
||||
},
|
||||
assertion: require.NoError,
|
||||
},
|
||||
@@ -107,14 +122,14 @@ func TestScanFlagGroup_ToOptions(t *testing.T) {
|
||||
viper.Set(flag.SkipDirsFlag.ConfigName, tt.fields.skipDirs)
|
||||
viper.Set(flag.SkipFilesFlag.ConfigName, tt.fields.skipFiles)
|
||||
viper.Set(flag.OfflineScanFlag.ConfigName, tt.fields.offlineScan)
|
||||
viper.Set(flag.SecurityChecksFlag.ConfigName, tt.fields.securityChecks)
|
||||
viper.Set(flag.ScannersFlag.ConfigName, tt.fields.scanners)
|
||||
|
||||
// Assert options
|
||||
f := &flag.ScanFlagGroup{
|
||||
SkipDirs: &flag.SkipDirsFlag,
|
||||
SkipFiles: &flag.SkipFilesFlag,
|
||||
OfflineScan: &flag.OfflineScanFlag,
|
||||
SecurityChecks: &flag.SecurityChecksFlag,
|
||||
Scanners: &flag.ScannersFlag,
|
||||
}
|
||||
|
||||
got, err := f.ToOptions(tt.args)
|
||||
|
||||
@@ -51,7 +51,10 @@ type runner struct {
|
||||
}
|
||||
|
||||
func newRunner(flagOpts flag.Options, cluster string) *runner {
|
||||
return &runner{flagOpts, cluster}
|
||||
return &runner{
|
||||
flagOpts,
|
||||
cluster,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error {
|
||||
@@ -90,11 +93,11 @@ func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error
|
||||
if err = yaml.Unmarshal(cs, &complianceSpec); err != nil {
|
||||
return xerrors.Errorf("yaml unmarshal error: %w", err)
|
||||
}
|
||||
securityChecks, err := complianceSpec.SecurityChecks()
|
||||
scanners, err := complianceSpec.Scanners()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("security check error: %w", err)
|
||||
return xerrors.Errorf("scanner error: %w", err)
|
||||
}
|
||||
r.flagOpts.ScanOptions.SecurityChecks = securityChecks
|
||||
r.flagOpts.ScanOptions.Scanners = scanners
|
||||
}
|
||||
|
||||
rpt, err := s.Scan(ctx, artifacts)
|
||||
@@ -117,7 +120,8 @@ func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error
|
||||
return cr.Write(complianceReport, cr.Option{
|
||||
Format: r.flagOpts.Format,
|
||||
Report: r.flagOpts.ReportFormat,
|
||||
Output: r.flagOpts.Output})
|
||||
Output: r.flagOpts.Output,
|
||||
})
|
||||
}
|
||||
|
||||
if err := report.Write(rpt, report.Option{
|
||||
@@ -126,7 +130,7 @@ func (r *runner) run(ctx context.Context, artifacts []*artifacts.Artifact) error
|
||||
Output: r.flagOpts.Output,
|
||||
Severities: r.flagOpts.Severities,
|
||||
Components: r.flagOpts.Components,
|
||||
SecurityChecks: r.flagOpts.ScanOptions.SecurityChecks,
|
||||
Scanners: r.flagOpts.ScanOptions.Scanners,
|
||||
}); err != nil {
|
||||
return xerrors.Errorf("unable to write results: %w", err)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ type Option struct {
|
||||
Output io.Writer
|
||||
Severities []dbTypes.Severity
|
||||
ColumnHeading []string
|
||||
SecurityChecks []string
|
||||
Scanners []string
|
||||
Components []string
|
||||
}
|
||||
|
||||
@@ -135,10 +135,13 @@ func Write(report Report, option Option) error {
|
||||
|
||||
switch option.Format {
|
||||
case jsonFormat:
|
||||
jwriter := JSONWriter{Output: option.Output, Report: option.Report}
|
||||
jwriter := JSONWriter{
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
}
|
||||
return jwriter.Write(report)
|
||||
case tableFormat:
|
||||
separatedReports := separateMisconfigReports(report, option.SecurityChecks, option.Components)
|
||||
separatedReports := separateMisconfigReports(report, option.Scanners, option.Components)
|
||||
|
||||
if option.Report == summaryReport {
|
||||
target := fmt.Sprintf("Summary Report for %s", report.ClusterName)
|
||||
@@ -150,7 +153,7 @@ func Write(report Report, option Option) error {
|
||||
Output: option.Output,
|
||||
Report: option.Report,
|
||||
Severities: option.Severities,
|
||||
ColumnHeading: ColumnHeading(option.SecurityChecks, option.Components, r.columns),
|
||||
ColumnHeading: ColumnHeading(option.Scanners, option.Components, r.columns),
|
||||
}
|
||||
|
||||
if err := writer.Write(r.report); err != nil {
|
||||
@@ -169,11 +172,11 @@ type reports struct {
|
||||
columns []string
|
||||
}
|
||||
|
||||
// separateMisconfigReports returns 3 reports based on securityChecks and components flags,
|
||||
// separateMisconfigReports returns 3 reports based on scanners and components flags,
|
||||
// - misconfiguration report
|
||||
// - rbac report
|
||||
// - infra checks report
|
||||
func separateMisconfigReports(k8sReport Report, securityChecks, components []string) []reports {
|
||||
func separateMisconfigReports(k8sReport Report, scanners, components []string) []reports {
|
||||
|
||||
workloadMisconfig := make([]Resource, 0)
|
||||
infraMisconfig := make([]Resource, 0)
|
||||
@@ -181,7 +184,7 @@ func separateMisconfigReports(k8sReport Report, securityChecks, components []str
|
||||
|
||||
for _, misConfig := range k8sReport.Misconfigurations {
|
||||
switch {
|
||||
case slices.Contains(securityChecks, types.SecurityCheckRbac) && rbacResource(misConfig):
|
||||
case slices.Contains(scanners, types.RBACScanner) && rbacResource(misConfig):
|
||||
rbacAssessment = append(rbacAssessment, misConfig)
|
||||
case infraResource(misConfig):
|
||||
workload, infra := splitInfraAndWorkloadResources(misConfig)
|
||||
@@ -194,7 +197,7 @@ func separateMisconfigReports(k8sReport Report, securityChecks, components []str
|
||||
workloadMisconfig = append(workloadMisconfig, workload)
|
||||
}
|
||||
|
||||
case slices.Contains(securityChecks, types.SecurityCheckConfig) && !rbacResource(misConfig):
|
||||
case slices.Contains(scanners, types.MisconfigScanner) && !rbacResource(misConfig):
|
||||
if slices.Contains(components, workloadComponent) {
|
||||
workloadMisconfig = append(workloadMisconfig, misConfig)
|
||||
}
|
||||
@@ -203,7 +206,7 @@ func separateMisconfigReports(k8sReport Report, securityChecks, components []str
|
||||
|
||||
r := make([]reports, 0)
|
||||
|
||||
if shouldAddWorkloadReport(securityChecks) {
|
||||
if shouldAddWorkloadReport(scanners) {
|
||||
workloadReport := Report{
|
||||
SchemaVersion: 0,
|
||||
ClusterName: k8sReport.ClusterName,
|
||||
@@ -215,11 +218,14 @@ func separateMisconfigReports(k8sReport Report, securityChecks, components []str
|
||||
if (slices.Contains(components, workloadComponent) &&
|
||||
len(workloadMisconfig) > 0) ||
|
||||
len(k8sReport.Vulnerabilities) > 0 {
|
||||
r = append(r, reports{report: workloadReport, columns: WorkloadColumns()})
|
||||
r = append(r, reports{
|
||||
report: workloadReport,
|
||||
columns: WorkloadColumns(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if slices.Contains(securityChecks, types.SecurityCheckRbac) && len(rbacAssessment) > 0 {
|
||||
if slices.Contains(scanners, types.RBACScanner) && len(rbacAssessment) > 0 {
|
||||
r = append(r, reports{
|
||||
report: Report{
|
||||
SchemaVersion: 0,
|
||||
@@ -231,7 +237,7 @@ func separateMisconfigReports(k8sReport Report, securityChecks, components []str
|
||||
})
|
||||
}
|
||||
|
||||
if slices.Contains(securityChecks, types.SecurityCheckConfig) &&
|
||||
if slices.Contains(scanners, types.MisconfigScanner) &&
|
||||
slices.Contains(components, infraComponent) &&
|
||||
len(infraMisconfig) > 0 {
|
||||
|
||||
@@ -357,8 +363,8 @@ func copyResult(r types.Result, misconfigs []types.DetectedMisconfiguration) typ
|
||||
}
|
||||
}
|
||||
|
||||
func shouldAddWorkloadReport(securityChecks []string) bool {
|
||||
return slices.Contains(securityChecks, types.SecurityCheckConfig) ||
|
||||
slices.Contains(securityChecks, types.SecurityCheckVulnerability) ||
|
||||
slices.Contains(securityChecks, types.SecurityCheckSecret)
|
||||
func shouldAddWorkloadReport(scanners []string) bool {
|
||||
return slices.Contains(scanners, types.MisconfigScanner) ||
|
||||
slices.Contains(scanners, types.VulnerabilityScanner) ||
|
||||
slices.Contains(scanners, types.SecretScanner)
|
||||
}
|
||||
|
||||
@@ -19,15 +19,45 @@ var (
|
||||
Kind: "Deploy",
|
||||
Name: "orion",
|
||||
Results: types.Results{
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{ID: "ID100", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "ID101", Status: types.StatusFailure, Severity: "MEDIUM"},
|
||||
{ID: "ID102", Status: types.StatusFailure, Severity: "HIGH"},
|
||||
{ID: "ID103", Status: types.StatusFailure, Severity: "CRITICAL"},
|
||||
{ID: "ID104", Status: types.StatusFailure, Severity: "UNKNOWN"},
|
||||
{ID: "ID105", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "ID106", Status: types.StatusFailure, Severity: "HIGH"},
|
||||
}},
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
{
|
||||
ID: "ID102",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
{
|
||||
ID: "ID103",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "CRITICAL",
|
||||
},
|
||||
{
|
||||
ID: "ID104",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "UNKNOWN",
|
||||
},
|
||||
{
|
||||
ID: "ID105",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID106",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -36,15 +66,38 @@ var (
|
||||
Kind: "Deploy",
|
||||
Name: "orion",
|
||||
Results: types.Results{
|
||||
{Vulnerabilities: []types.DetectedVulnerability{
|
||||
{VulnerabilityID: "CVE-2022-1111", Vulnerability: dbTypes.Vulnerability{Severity: "LOW"}},
|
||||
{VulnerabilityID: "CVE-2022-2222", Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"}},
|
||||
{VulnerabilityID: "CVE-2022-3333", Vulnerability: dbTypes.Vulnerability{Severity: "HIGH"}},
|
||||
{VulnerabilityID: "CVE-2022-4444", Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"}},
|
||||
{VulnerabilityID: "CVE-2022-5555", Vulnerability: dbTypes.Vulnerability{Severity: "UNKNOWN"}},
|
||||
{VulnerabilityID: "CVE-2022-6666", Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"}},
|
||||
{VulnerabilityID: "CVE-2022-7777", Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"}},
|
||||
}},
|
||||
{
|
||||
Vulnerabilities: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-1111",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-2222",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-3333",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "HIGH"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-4444",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-5555",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "UNKNOWN"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-6666",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-7777",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -53,24 +106,77 @@ var (
|
||||
Kind: "Deploy",
|
||||
Name: "orion",
|
||||
Results: types.Results{
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{ID: "ID100", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "ID101", Status: types.StatusFailure, Severity: "MEDIUM"},
|
||||
{ID: "ID102", Status: types.StatusFailure, Severity: "HIGH"},
|
||||
{ID: "ID103", Status: types.StatusFailure, Severity: "CRITICAL"},
|
||||
{ID: "ID104", Status: types.StatusFailure, Severity: "UNKNOWN"},
|
||||
{ID: "ID105", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "ID106", Status: types.StatusFailure, Severity: "HIGH"},
|
||||
}},
|
||||
{Vulnerabilities: []types.DetectedVulnerability{
|
||||
{VulnerabilityID: "CVE-2022-1111", Vulnerability: dbTypes.Vulnerability{Severity: "LOW"}},
|
||||
{VulnerabilityID: "CVE-2022-2222", Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"}},
|
||||
{VulnerabilityID: "CVE-2022-3333", Vulnerability: dbTypes.Vulnerability{Severity: "HIGH"}},
|
||||
{VulnerabilityID: "CVE-2022-4444", Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"}},
|
||||
{VulnerabilityID: "CVE-2022-5555", Vulnerability: dbTypes.Vulnerability{Severity: "UNKNOWN"}},
|
||||
{VulnerabilityID: "CVE-2022-6666", Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"}},
|
||||
{VulnerabilityID: "CVE-2022-7777", Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"}},
|
||||
}},
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
{
|
||||
ID: "ID102",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
{
|
||||
ID: "ID103",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "CRITICAL",
|
||||
},
|
||||
{
|
||||
ID: "ID104",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "UNKNOWN",
|
||||
},
|
||||
{
|
||||
ID: "ID105",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "ID106",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Vulnerabilities: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-1111",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-2222",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-3333",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "HIGH"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-4444",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-5555",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "UNKNOWN"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-6666",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "CRITICAL"},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-7777",
|
||||
Vulnerability: dbTypes.Vulnerability{Severity: "MEDIUM"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -97,9 +203,15 @@ var (
|
||||
Kind: "Role",
|
||||
Name: "system::leader-locking-kube-controller-manager",
|
||||
Results: types.Results{
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{ID: "ID100", Status: types.StatusFailure, Severity: "MEDIUM"},
|
||||
}},
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -108,10 +220,18 @@ var (
|
||||
Kind: "Deploy",
|
||||
Name: "lua",
|
||||
Results: types.Results{
|
||||
{Secrets: []ftypes.SecretFinding{
|
||||
{RuleID: "secret1", Severity: "CRITICAL"},
|
||||
{RuleID: "secret2", Severity: "MEDIUM"},
|
||||
}},
|
||||
{
|
||||
Secrets: []ftypes.SecretFinding{
|
||||
{
|
||||
RuleID: "secret1",
|
||||
Severity: "CRITICAL",
|
||||
},
|
||||
{
|
||||
RuleID: "secret2",
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -120,14 +240,36 @@ var (
|
||||
Kind: "Pod",
|
||||
Name: "kube-apiserver",
|
||||
Results: types.Results{
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{ID: "KSV-ID100", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "KSV-ID101", Status: types.StatusFailure, Severity: "MEDIUM"},
|
||||
{ID: "KSV-ID102", Status: types.StatusFailure, Severity: "HIGH"},
|
||||
{
|
||||
Misconfigurations: []types.DetectedMisconfiguration{
|
||||
{
|
||||
ID: "KSV-ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "KSV-ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
{
|
||||
ID: "KSV-ID102",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "HIGH",
|
||||
},
|
||||
|
||||
{ID: "KCV-ID100", Status: types.StatusFailure, Severity: "LOW"},
|
||||
{ID: "KCV-ID101", Status: types.StatusFailure, Severity: "MEDIUM"},
|
||||
}},
|
||||
{
|
||||
ID: "KCV-ID100",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "LOW",
|
||||
},
|
||||
{
|
||||
ID: "KCV-ID101",
|
||||
Status: types.StatusFailure,
|
||||
Severity: "MEDIUM",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -141,8 +283,14 @@ func TestReport_consolidate(t *testing.T) {
|
||||
{
|
||||
name: "report with both misconfigs and vulnerabilities",
|
||||
report: Report{
|
||||
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
|
||||
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
|
||||
Vulnerabilities: []Resource{
|
||||
deployOrionWithVulns,
|
||||
cronjobHelloWithVulns,
|
||||
},
|
||||
Misconfigurations: []Resource{
|
||||
deployOrionWithMisconfigs,
|
||||
podPrometheusWithMisconfigs,
|
||||
},
|
||||
},
|
||||
expectedFindings: map[string]Resource{
|
||||
"default/deploy/orion": deployOrionWithBothVulnsAndMisconfigs,
|
||||
@@ -153,7 +301,10 @@ func TestReport_consolidate(t *testing.T) {
|
||||
{
|
||||
name: "report with only misconfigurations",
|
||||
report: Report{
|
||||
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
|
||||
Misconfigurations: []Resource{
|
||||
deployOrionWithMisconfigs,
|
||||
podPrometheusWithMisconfigs,
|
||||
},
|
||||
},
|
||||
expectedFindings: map[string]Resource{
|
||||
"default/deploy/orion": deployOrionWithMisconfigs,
|
||||
@@ -163,7 +314,10 @@ func TestReport_consolidate(t *testing.T) {
|
||||
{
|
||||
name: "report with only vulnerabilities",
|
||||
report: Report{
|
||||
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
|
||||
Vulnerabilities: []Resource{
|
||||
deployOrionWithVulns,
|
||||
cronjobHelloWithVulns,
|
||||
},
|
||||
},
|
||||
expectedFindings: map[string]Resource{
|
||||
"default/deploy/orion": deployOrionWithVulns,
|
||||
@@ -194,10 +348,22 @@ func TestResource_fullname(t *testing.T) {
|
||||
expected string
|
||||
resource Resource
|
||||
}{
|
||||
{"default/deploy/orion", deployOrionWithBothVulnsAndMisconfigs},
|
||||
{"default/deploy/orion", deployOrionWithMisconfigs},
|
||||
{"default/cronjob/hello", cronjobHelloWithVulns},
|
||||
{"default/pod/prometheus", podPrometheusWithMisconfigs},
|
||||
{
|
||||
"default/deploy/orion",
|
||||
deployOrionWithBothVulnsAndMisconfigs,
|
||||
},
|
||||
{
|
||||
"default/deploy/orion",
|
||||
deployOrionWithMisconfigs,
|
||||
},
|
||||
{
|
||||
"default/cronjob/hello",
|
||||
cronjobHelloWithVulns,
|
||||
},
|
||||
{
|
||||
"default/pod/prometheus",
|
||||
podPrometheusWithMisconfigs,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -216,22 +382,34 @@ func TestResourceFailed(t *testing.T) {
|
||||
{
|
||||
name: "report with both misconfigs and vulnerabilities",
|
||||
report: Report{
|
||||
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
|
||||
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
|
||||
Vulnerabilities: []Resource{
|
||||
deployOrionWithVulns,
|
||||
cronjobHelloWithVulns,
|
||||
},
|
||||
Misconfigurations: []Resource{
|
||||
deployOrionWithMisconfigs,
|
||||
podPrometheusWithMisconfigs,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "report with only misconfigurations",
|
||||
report: Report{
|
||||
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
|
||||
Misconfigurations: []Resource{
|
||||
deployOrionWithMisconfigs,
|
||||
podPrometheusWithMisconfigs,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "report with only vulnerabilities",
|
||||
report: Report{
|
||||
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
|
||||
Vulnerabilities: []Resource{
|
||||
deployOrionWithVulns,
|
||||
cronjobHelloWithVulns,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
@@ -285,30 +463,49 @@ func Test_rbacResource(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_separateMisconfigReports(t *testing.T) {
|
||||
k8sReport := Report{Misconfigurations: []Resource{
|
||||
k8sReport := Report{
|
||||
Misconfigurations: []Resource{
|
||||
{Kind: "Role"},
|
||||
{Kind: "Deployment"},
|
||||
{Kind: "StatefulSet"},
|
||||
{Kind: "Pod", Namespace: "kube-system", Results: []types.Result{
|
||||
{
|
||||
Kind: "Pod",
|
||||
Namespace: "kube-system",
|
||||
Results: []types.Result{
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{{ID: "KCV-0001"}}},
|
||||
{Misconfigurations: []types.DetectedMisconfiguration{{ID: "KSV-0001"}}},
|
||||
}},
|
||||
}}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
k8sReport Report
|
||||
securityChecks []string
|
||||
scanners []string
|
||||
components []string
|
||||
expectedReports []Report
|
||||
}{
|
||||
{
|
||||
name: "Config, Rbac, and Infra Reports",
|
||||
k8sReport: k8sReport,
|
||||
securityChecks: []string{types.SecurityCheckConfig, types.SecurityCheckRbac},
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
expectedReports: []Report{ // the order matter for the test
|
||||
{Misconfigurations: []Resource{{Kind: "Deployment"}, {Kind: "StatefulSet"}, {Kind: "Pod"}}},
|
||||
scanners: []string{
|
||||
types.MisconfigScanner,
|
||||
types.RBACScanner,
|
||||
},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
expectedReports: []Report{
|
||||
// the order matter for the test
|
||||
{
|
||||
Misconfigurations: []Resource{
|
||||
{Kind: "Deployment"},
|
||||
{Kind: "StatefulSet"},
|
||||
{Kind: "Pod"},
|
||||
},
|
||||
},
|
||||
{Misconfigurations: []Resource{{Kind: "Role"}}},
|
||||
{Misconfigurations: []Resource{{Kind: "Pod"}}},
|
||||
},
|
||||
@@ -316,17 +513,27 @@ func Test_separateMisconfigReports(t *testing.T) {
|
||||
{
|
||||
name: "Config and Infra for the same resource",
|
||||
k8sReport: k8sReport,
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
expectedReports: []Report{ // the order matter for the test
|
||||
{Misconfigurations: []Resource{{Kind: "Deployment"}, {Kind: "StatefulSet"}, {Kind: "Pod"}}},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
expectedReports: []Report{
|
||||
// the order matter for the test
|
||||
{
|
||||
Misconfigurations: []Resource{
|
||||
{Kind: "Deployment"},
|
||||
{Kind: "StatefulSet"},
|
||||
{Kind: "Pod"},
|
||||
},
|
||||
},
|
||||
{Misconfigurations: []Resource{{Kind: "Pod"}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Role Report Only",
|
||||
k8sReport: k8sReport,
|
||||
securityChecks: []string{types.SecurityCheckRbac},
|
||||
scanners: []string{types.RBACScanner},
|
||||
expectedReports: []Report{
|
||||
{Misconfigurations: []Resource{{Kind: "Role"}}},
|
||||
},
|
||||
@@ -334,16 +541,22 @@ func Test_separateMisconfigReports(t *testing.T) {
|
||||
{
|
||||
name: "Config Report Only",
|
||||
k8sReport: k8sReport,
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{workloadComponent},
|
||||
expectedReports: []Report{
|
||||
{Misconfigurations: []Resource{{Kind: "Deployment"}, {Kind: "StatefulSet"}, {Kind: "Pod"}}},
|
||||
{
|
||||
Misconfigurations: []Resource{
|
||||
{Kind: "Deployment"},
|
||||
{Kind: "StatefulSet"},
|
||||
{Kind: "Pod"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Infra Report Only",
|
||||
k8sReport: k8sReport,
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{infraComponent},
|
||||
expectedReports: []Report{
|
||||
{Misconfigurations: []Resource{{Kind: "Pod"}}},
|
||||
@@ -355,7 +568,7 @@ func Test_separateMisconfigReports(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
reports := separateMisconfigReports(tt.k8sReport, tt.securityChecks, tt.components)
|
||||
reports := separateMisconfigReports(tt.k8sReport, tt.scanners, tt.components)
|
||||
assert.Equal(t, len(tt.expectedReports), len(reports))
|
||||
|
||||
for i := range reports {
|
||||
@@ -381,7 +594,7 @@ func TestReportWrite_Summary(t *testing.T) {
|
||||
name string
|
||||
report Report
|
||||
opt Option
|
||||
securityChecks []string
|
||||
scanners []string
|
||||
components []string
|
||||
severities []dbTypes.Severity
|
||||
expectedOutput string
|
||||
@@ -392,7 +605,7 @@ func TestReportWrite_Summary(t *testing.T) {
|
||||
ClusterName: "test",
|
||||
Misconfigurations: []Resource{deployOrionWithMisconfigs},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
@@ -414,7 +627,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
ClusterName: "test",
|
||||
Vulnerabilities: []Resource{deployOrionWithVulns},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckVulnerability},
|
||||
scanners: []string{types.VulnerabilityScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
@@ -435,7 +648,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
ClusterName: "test",
|
||||
Misconfigurations: []Resource{roleWithMisconfig},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckRbac},
|
||||
scanners: []string{types.RBACScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
@@ -456,7 +669,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
ClusterName: "test",
|
||||
Vulnerabilities: []Resource{deployLuaWithSecrets},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckSecret},
|
||||
scanners: []string{types.SecretScanner},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
@@ -477,7 +690,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
ClusterName: "test",
|
||||
Misconfigurations: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{infraComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
@@ -499,7 +712,11 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
ClusterName: "test",
|
||||
Misconfigurations: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckVulnerability, types.SecurityCheckConfig, types.SecurityCheckSecret},
|
||||
scanners: []string{
|
||||
types.VulnerabilityScanner,
|
||||
types.MisconfigScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{workloadComponent},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
@@ -516,14 +733,21 @@ Workload Assessment
|
||||
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
},
|
||||
{
|
||||
name: "apiserver, all security-checks and serverities",
|
||||
name: "apiserver, all scanners and serverities",
|
||||
report: Report{
|
||||
ClusterName: "test",
|
||||
Misconfigurations: []Resource{apiseverPodWithMisconfigAndInfra},
|
||||
},
|
||||
securityChecks: []string{types.SecurityCheckConfig, types.SecurityCheckVulnerability,
|
||||
types.SecurityCheckRbac, types.SecurityCheckSecret},
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
scanners: []string{
|
||||
types.MisconfigScanner,
|
||||
types.VulnerabilityScanner,
|
||||
types.RBACScanner,
|
||||
types.SecretScanner,
|
||||
},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
severities: allSeverities,
|
||||
expectedOutput: `Summary Report for test
|
||||
=======================
|
||||
@@ -559,7 +783,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
|
||||
Format: "table",
|
||||
Report: "summary",
|
||||
Output: &output,
|
||||
SecurityChecks: tc.securityChecks,
|
||||
Scanners: tc.scanners,
|
||||
Severities: tc.severities,
|
||||
Components: tc.components,
|
||||
}
|
||||
|
||||
@@ -35,24 +35,27 @@ func NewSummaryWriter(output io.Writer, requiredSevs []dbTypes.Severity, columnH
|
||||
}
|
||||
}
|
||||
|
||||
func ColumnHeading(securityChecks, components, availableColumns []string) []string {
|
||||
columns := []string{NamespaceColumn, ResourceColumn}
|
||||
func ColumnHeading(scanners, components, availableColumns []string) []string {
|
||||
columns := []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
}
|
||||
securityOptions := make(map[string]interface{}, 0)
|
||||
//maintain column order (vuln,config,secret)
|
||||
for _, check := range securityChecks {
|
||||
for _, check := range scanners {
|
||||
switch check {
|
||||
case types.SecurityCheckVulnerability:
|
||||
case types.VulnerabilityScanner:
|
||||
securityOptions[VulnerabilitiesColumn] = nil
|
||||
case types.SecurityCheckConfig:
|
||||
case types.MisconfigScanner:
|
||||
if slices.Contains(components, workloadComponent) {
|
||||
securityOptions[MisconfigurationsColumn] = nil
|
||||
}
|
||||
if slices.Contains(components, infraComponent) {
|
||||
securityOptions[InfraAssessmentColumn] = nil
|
||||
}
|
||||
case types.SecurityCheckSecret:
|
||||
case types.SecretScanner:
|
||||
securityOptions[SecretsColumn] = nil
|
||||
case types.SecurityCheckRbac:
|
||||
case types.RBACScanner:
|
||||
securityOptions[RbacAssessmentColumn] = nil
|
||||
}
|
||||
}
|
||||
@@ -94,7 +97,10 @@ func (s SummaryWriter) Write(report Report) error {
|
||||
}
|
||||
vCount, mCount, sCount := accumulateSeverityCounts(finding)
|
||||
name := fmt.Sprintf("%s/%s", finding.Kind, finding.Name)
|
||||
rowParts := []string{finding.Namespace, name}
|
||||
rowParts := []string{
|
||||
finding.Namespace,
|
||||
name,
|
||||
}
|
||||
|
||||
if slices.Contains(s.ColumnsHeading, VulnerabilitiesColumn) {
|
||||
rowParts = append(rowParts, s.generateSummary(vCount)...)
|
||||
@@ -140,9 +146,13 @@ func (s SummaryWriter) generateSummary(sevCount map[string]int) []string {
|
||||
}
|
||||
|
||||
func getRequiredSeverities(requiredSevs []dbTypes.Severity) ([]string, []string) {
|
||||
requiredSevOrder := []dbTypes.Severity{dbTypes.SeverityCritical,
|
||||
dbTypes.SeverityHigh, dbTypes.SeverityMedium,
|
||||
dbTypes.SeverityLow, dbTypes.SeverityUnknown}
|
||||
requiredSevOrder := []dbTypes.Severity{
|
||||
dbTypes.SeverityCritical,
|
||||
dbTypes.SeverityHigh,
|
||||
dbTypes.SeverityMedium,
|
||||
dbTypes.SeverityLow,
|
||||
dbTypes.SeverityUnknown,
|
||||
}
|
||||
var severities []string
|
||||
var severityHeadings []string
|
||||
for _, sev := range requiredSevOrder {
|
||||
@@ -178,11 +188,20 @@ func accumulateSeverityCounts(finding Resource) (map[string]int, map[string]int,
|
||||
func configureHeader(s SummaryWriter, t *table.Table, columnHeading []string) {
|
||||
sevCount := len(s.Severities)
|
||||
if len(columnHeading) > 2 {
|
||||
headerRow := []string{columnHeading[0], columnHeading[1]}
|
||||
headerRow := []string{
|
||||
columnHeading[0],
|
||||
columnHeading[1],
|
||||
}
|
||||
// vulnerabilities headings
|
||||
count := len(columnHeading) - len(headerRow)
|
||||
colSpan := []int{1, 1}
|
||||
headerAlignment := []table.Alignment{table.AlignLeft, table.AlignLeft}
|
||||
colSpan := []int{
|
||||
1,
|
||||
1,
|
||||
}
|
||||
headerAlignment := []table.Alignment{
|
||||
table.AlignLeft,
|
||||
table.AlignLeft,
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
headerRow = append(headerRow, s.SeverityHeadings...)
|
||||
colSpan = append(colSpan, sevCount)
|
||||
|
||||
@@ -10,67 +10,102 @@ import (
|
||||
)
|
||||
|
||||
func TestReport_ColumnHeading(t *testing.T) {
|
||||
allSecurityChecks := []string{
|
||||
types.SecurityCheckVulnerability,
|
||||
types.SecurityCheckConfig,
|
||||
types.SecurityCheckSecret,
|
||||
types.SecurityCheckRbac,
|
||||
allScanners := []string{
|
||||
types.VulnerabilityScanner,
|
||||
types.MisconfigScanner,
|
||||
types.SecretScanner,
|
||||
types.RBACScanner,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
securityChecks []string
|
||||
scanners []string
|
||||
components []string
|
||||
availableColumns []string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "filter workload columns",
|
||||
securityChecks: allSecurityChecks,
|
||||
scanners: allScanners,
|
||||
availableColumns: WorkloadColumns(),
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
want: []string{NamespaceColumn, ResourceColumn, VulnerabilitiesColumn, MisconfigurationsColumn, SecretsColumn},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
VulnerabilitiesColumn,
|
||||
MisconfigurationsColumn,
|
||||
SecretsColumn,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter rbac columns",
|
||||
securityChecks: allSecurityChecks,
|
||||
scanners: allScanners,
|
||||
components: []string{},
|
||||
availableColumns: RoleColumns(),
|
||||
want: []string{NamespaceColumn, ResourceColumn, RbacAssessmentColumn},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
RbacAssessmentColumn,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter infra columns",
|
||||
securityChecks: allSecurityChecks,
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
scanners: allScanners,
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
availableColumns: InfraColumns(),
|
||||
want: []string{NamespaceColumn, ResourceColumn, InfraAssessmentColumn},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
InfraAssessmentColumn,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "config column only",
|
||||
securityChecks: []string{types.SecurityCheckConfig},
|
||||
components: []string{workloadComponent, infraComponent},
|
||||
scanners: []string{types.MisconfigScanner},
|
||||
components: []string{
|
||||
workloadComponent,
|
||||
infraComponent,
|
||||
},
|
||||
availableColumns: WorkloadColumns(),
|
||||
want: []string{NamespaceColumn, ResourceColumn, MisconfigurationsColumn},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
MisconfigurationsColumn,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "secret column only",
|
||||
securityChecks: []string{types.SecurityCheckSecret},
|
||||
scanners: []string{types.SecretScanner},
|
||||
components: []string{},
|
||||
availableColumns: WorkloadColumns(),
|
||||
want: []string{NamespaceColumn, ResourceColumn, SecretsColumn},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
SecretsColumn,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vuln column only",
|
||||
securityChecks: []string{types.SecurityCheckVulnerability},
|
||||
scanners: []string{types.VulnerabilityScanner},
|
||||
components: []string{},
|
||||
availableColumns: WorkloadColumns(),
|
||||
want: []string{NamespaceColumn, ResourceColumn, VulnerabilitiesColumn},
|
||||
want: []string{
|
||||
NamespaceColumn,
|
||||
ResourceColumn,
|
||||
VulnerabilitiesColumn,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
column := ColumnHeading(tt.securityChecks, tt.components, tt.availableColumns)
|
||||
column := ColumnHeading(tt.scanners, tt.components, tt.availableColumns)
|
||||
if !assert.Equal(t, column, tt.want) {
|
||||
t.Error(fmt.Errorf("TestReport_ColumnHeading want %v got %v", tt.want, column))
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ type Scanner struct {
|
||||
}
|
||||
|
||||
func NewScanner(cluster string, runner cmd.Runner, opts flag.Options) *Scanner {
|
||||
return &Scanner{cluster, runner, opts}
|
||||
return &Scanner{
|
||||
cluster,
|
||||
runner,
|
||||
opts,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scanner) Scan(ctx context.Context, artifacts []*artifacts.Artifact) (report.Report, error) {
|
||||
@@ -59,7 +63,7 @@ func (s *Scanner) Scan(ctx context.Context, artifacts []*artifacts.Artifact) (re
|
||||
for _, artifact := range artifacts {
|
||||
bar.Increment()
|
||||
|
||||
if shouldScanVulnsOrSecrets(s.opts.SecurityChecks) {
|
||||
if shouldScanVulnsOrSecrets(s.opts.Scanners) {
|
||||
resources, err := s.scanVulns(ctx, artifact)
|
||||
if err != nil {
|
||||
return report.Report{}, xerrors.Errorf("scanning vulnerabilities error: %w", err)
|
||||
@@ -67,7 +71,7 @@ func (s *Scanner) Scan(ctx context.Context, artifacts []*artifacts.Artifact) (re
|
||||
vulns = append(vulns, resources...)
|
||||
}
|
||||
|
||||
if local.ShouldScanMisconfigOrRbac(s.opts.SecurityChecks) {
|
||||
if local.ShouldScanMisconfigOrRbac(s.opts.Scanners) {
|
||||
resource, err := s.scanMisconfigs(ctx, artifact)
|
||||
if err != nil {
|
||||
return report.Report{}, xerrors.Errorf("scanning misconfigurations error: %w", err)
|
||||
@@ -137,7 +141,7 @@ func (s *Scanner) filter(ctx context.Context, r types.Report, artifact *artifact
|
||||
return report.CreateResource(artifact, r, nil), nil
|
||||
}
|
||||
|
||||
func shouldScanVulnsOrSecrets(securityChecks []string) bool {
|
||||
return slices.Contains(securityChecks, types.SecurityCheckVulnerability) ||
|
||||
slices.Contains(securityChecks, types.SecurityCheckSecret)
|
||||
func shouldScanVulnsOrSecrets(scanners []string) bool {
|
||||
return slices.Contains(scanners, types.VulnerabilityScanner) ||
|
||||
slices.Contains(scanners, types.SecretScanner)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,10 @@ func NewScanner(scannerOptions ScannerOption, opts ...Option) Scanner {
|
||||
opt(o)
|
||||
}
|
||||
|
||||
return Scanner{customHeaders: scannerOptions.CustomHeaders, client: o.rpcClient}
|
||||
return Scanner{
|
||||
customHeaders: scannerOptions.CustomHeaders,
|
||||
client: o.rpcClient,
|
||||
}
|
||||
}
|
||||
|
||||
// Scan scans the image
|
||||
@@ -79,7 +82,7 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys
|
||||
BlobIds: blobKeys,
|
||||
Options: &rpc.ScanOptions{
|
||||
VulnType: opts.VulnType,
|
||||
SecurityChecks: opts.SecurityChecks,
|
||||
Scanners: opts.Scanners,
|
||||
ListAllPackages: opts.ListAllPackages,
|
||||
LicenseCategories: licenseCategories,
|
||||
},
|
||||
|
||||
@@ -44,7 +44,7 @@ func teeError(err error) error {
|
||||
func (s *ScanServer) Scan(ctx context.Context, in *rpcScanner.ScanRequest) (*rpcScanner.ScanResponse, error) {
|
||||
options := types.ScanOptions{
|
||||
VulnType: in.Options.VulnType,
|
||||
SecurityChecks: in.Options.SecurityChecks,
|
||||
Scanners: in.Options.Scanners,
|
||||
ListAllPackages: in.Options.ListAllPackages,
|
||||
}
|
||||
results, os, err := s.localScanner.Scan(ctx, in.Target, in.ArtifactId, in.BlobIds, options)
|
||||
@@ -95,7 +95,10 @@ func (s *CacheServer) MissingBlobs(_ context.Context, in *rpcCache.MissingBlobsR
|
||||
if err != nil {
|
||||
return nil, teeError(xerrors.Errorf("failed to get missing blobs: %w", err))
|
||||
}
|
||||
return &rpcCache.MissingBlobsResponse{MissingArtifact: missingArtifact, MissingBlobIds: blobIDs}, nil
|
||||
return &rpcCache.MissingBlobsResponse{
|
||||
MissingArtifact: missingArtifact,
|
||||
MissingBlobIds: blobIDs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteBlobs removes blobs by IDs
|
||||
|
||||
@@ -114,7 +114,7 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys
|
||||
}
|
||||
|
||||
// Scan packages for vulnerabilities
|
||||
if slices.Contains(options.SecurityChecks, types.SecurityCheckVulnerability) {
|
||||
if slices.Contains(options.Scanners, types.VulnerabilityScanner) {
|
||||
var vulnResults types.Results
|
||||
vulnResults, eosl, err = s.scanVulnerabilities(target, artifactDetail, options)
|
||||
if err != nil {
|
||||
@@ -132,19 +132,19 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys
|
||||
}
|
||||
|
||||
// Scan IaC config files
|
||||
if ShouldScanMisconfigOrRbac(options.SecurityChecks) {
|
||||
if ShouldScanMisconfigOrRbac(options.Scanners) {
|
||||
configResults := s.MisconfsToResults(artifactDetail.Misconfigurations)
|
||||
results = append(results, configResults...)
|
||||
}
|
||||
|
||||
// Scan secrets
|
||||
if slices.Contains(options.SecurityChecks, types.SecurityCheckSecret) {
|
||||
if slices.Contains(options.Scanners, types.SecretScanner) {
|
||||
secretResults := s.secretsToResults(artifactDetail.Secrets)
|
||||
results = append(results, secretResults...)
|
||||
}
|
||||
|
||||
// Scan licenses
|
||||
if slices.Contains(options.SecurityChecks, types.SecurityCheckLicense) {
|
||||
if slices.Contains(options.Scanners, types.LicenseScanner) {
|
||||
licenseResults := s.scanLicenses(artifactDetail, options.LicenseCategories)
|
||||
results = append(results, licenseResults...)
|
||||
}
|
||||
@@ -538,7 +538,7 @@ func mergePkgs(pkgs, pkgsFromCommands []ftypes.Package) []ftypes.Package {
|
||||
return pkgs
|
||||
}
|
||||
|
||||
func ShouldScanMisconfigOrRbac(securityChecks []string) bool {
|
||||
return slices.Contains(securityChecks, types.SecurityCheckConfig) ||
|
||||
slices.Contains(securityChecks, types.SecurityCheckRbac)
|
||||
func ShouldScanMisconfigOrRbac(scanners []string) bool {
|
||||
return slices.Contains(scanners, types.MisconfigScanner) ||
|
||||
slices.Contains(scanners, types.RBACScanner)
|
||||
}
|
||||
|
||||
@@ -42,8 +42,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -149,8 +152,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
ListAllPackages: true,
|
||||
},
|
||||
},
|
||||
@@ -297,8 +303,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
ListAllPackages: true,
|
||||
},
|
||||
},
|
||||
@@ -403,8 +412,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -483,8 +495,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -563,8 +578,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "fedora:27",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -636,8 +654,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "busybox:latest",
|
||||
layerIDs: []string{"sha256:a6d503001157aedc826853f9b67f26d35966221b158bff03849868ae4a821116"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -658,7 +679,7 @@ func TestScanner_Scan(t *testing.T) {
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -767,7 +788,7 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "/app/configs",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
SecurityChecks: []string{types.SecurityCheckConfig},
|
||||
Scanners: []string{types.MisconfigScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -916,8 +937,11 @@ func TestScanner_Scan(t *testing.T) {
|
||||
target: "alpine:latest",
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
VulnType: []string{
|
||||
types.VulnTypeOS,
|
||||
types.VulnTypeLibrary,
|
||||
},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/happy.yaml"},
|
||||
@@ -938,7 +962,7 @@ func TestScanner_Scan(t *testing.T) {
|
||||
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
|
||||
options: types.ScanOptions{
|
||||
VulnType: []string{types.VulnTypeLibrary},
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
Scanners: []string{types.VulnerabilityScanner},
|
||||
},
|
||||
},
|
||||
fixtures: []string{"testdata/fixtures/sad.yaml"},
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
// ScanOptions holds the attributes for scanning vulnerabilities
|
||||
type ScanOptions struct {
|
||||
VulnType []string
|
||||
SecurityChecks []string
|
||||
Scanners []string
|
||||
ScanRemovedPackages bool
|
||||
Platform string
|
||||
ListAllPackages bool
|
||||
|
||||
@@ -3,8 +3,8 @@ package types
|
||||
// VulnType represents vulnerability type
|
||||
type VulnType = string
|
||||
|
||||
// SecurityCheck represents the type of security check
|
||||
type SecurityCheck = string
|
||||
// Scanner represents the type of security scanning
|
||||
type Scanner = string
|
||||
|
||||
const (
|
||||
// VulnTypeUnknown is a vulnerability type of unknown
|
||||
@@ -16,29 +16,35 @@ const (
|
||||
// VulnTypeLibrary is a vulnerability type of programming language dependencies
|
||||
VulnTypeLibrary = VulnType("library")
|
||||
|
||||
// SecurityCheckUnknown is a security check of unknown
|
||||
SecurityCheckUnknown = SecurityCheck("unknown")
|
||||
// ScannerUnknown is the scanner of unknown
|
||||
ScannerUnknown = Scanner("unknown")
|
||||
|
||||
// SecurityCheckVulnerability is a security check of vulnerabilities
|
||||
SecurityCheckVulnerability = SecurityCheck("vuln")
|
||||
// VulnerabilityScanner is the scanner of vulnerabilities
|
||||
VulnerabilityScanner = Scanner("vuln")
|
||||
|
||||
// SecurityCheckConfig is a security check of misconfigurations
|
||||
SecurityCheckConfig = SecurityCheck("config")
|
||||
// MisconfigScanner is the scanner of misconfigurations
|
||||
MisconfigScanner = Scanner("config")
|
||||
|
||||
// SecurityCheckSecret is a security check of secrets
|
||||
SecurityCheckSecret = SecurityCheck("secret")
|
||||
// SecretScanner is the scanner of secrets
|
||||
SecretScanner = Scanner("secret")
|
||||
|
||||
// SecurityCheckRbac is a security check of rbac assessment
|
||||
SecurityCheckRbac = SecurityCheck("rbac")
|
||||
// RBACScanner is the scanner of rbac assessment
|
||||
RBACScanner = Scanner("rbac")
|
||||
|
||||
// SecurityCheckLicense is the security check of licenses
|
||||
SecurityCheckLicense = SecurityCheck("license")
|
||||
// LicenseScanner is the scanner of licenses
|
||||
LicenseScanner = Scanner("license")
|
||||
)
|
||||
|
||||
var (
|
||||
VulnTypes = []string{VulnTypeOS, VulnTypeLibrary}
|
||||
SecurityChecks = []string{
|
||||
SecurityCheckVulnerability, SecurityCheckConfig, SecurityCheckRbac,
|
||||
SecurityCheckSecret, SecurityCheckLicense,
|
||||
VulnTypes = []string{
|
||||
VulnTypeOS,
|
||||
VulnTypeLibrary,
|
||||
}
|
||||
Scanners = []string{
|
||||
VulnerabilityScanner,
|
||||
MisconfigScanner,
|
||||
RBACScanner,
|
||||
SecretScanner,
|
||||
LicenseScanner,
|
||||
}
|
||||
)
|
||||
|
||||
8
rpc/cache/service.pb.go
vendored
8
rpc/cache/service.pb.go
vendored
@@ -7,15 +7,13 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
common "github.com/aquasecurity/trivy/rpc/common"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
common "github.com/aquasecurity/trivy/rpc/common"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
48
rpc/cache/service.twirp.go
vendored
48
rpc/cache/service.twirp.go
vendored
@@ -3,40 +3,26 @@
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
import context "context"
|
||||
import fmt "fmt"
|
||||
import http "net/http"
|
||||
import ioutil "io/ioutil"
|
||||
import json "encoding/json"
|
||||
import strconv "strconv"
|
||||
import strings "strings"
|
||||
|
||||
http "net/http"
|
||||
import protojson "google.golang.org/protobuf/encoding/protojson"
|
||||
import proto "google.golang.org/protobuf/proto"
|
||||
import twirp "github.com/twitchtv/twirp"
|
||||
import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
|
||||
|
||||
ioutil "io/ioutil"
|
||||
import google_protobuf2 "google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
json "encoding/json"
|
||||
|
||||
strconv "strconv"
|
||||
|
||||
strings "strings"
|
||||
|
||||
protojson "google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
|
||||
twirp "github.com/twitchtv/twirp"
|
||||
|
||||
ctxsetters "github.com/twitchtv/twirp/ctxsetters"
|
||||
|
||||
google_protobuf2 "google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
bytes "bytes"
|
||||
|
||||
errors "errors"
|
||||
|
||||
io "io"
|
||||
|
||||
path "path"
|
||||
|
||||
url "net/url"
|
||||
)
|
||||
import bytes "bytes"
|
||||
import errors "errors"
|
||||
import io "io"
|
||||
import path "path"
|
||||
import url "net/url"
|
||||
|
||||
// Version compatibility assertion.
|
||||
// If the constant is not defined in the package, that likely means
|
||||
|
||||
@@ -7,13 +7,11 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
|
||||
common "github.com/aquasecurity/trivy/rpc/common"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
|
||||
common "github.com/aquasecurity/trivy/rpc/common"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -94,7 +92,8 @@ func (x *ScanRequest) GetOptions() *ScanOptions {
|
||||
return nil
|
||||
}
|
||||
|
||||
// cf. https://stackoverflow.com/questions/38886789/protobuf3-how-to-describe-map-of-repeated-string
|
||||
// cf.
|
||||
// https://stackoverflow.com/questions/38886789/protobuf3-how-to-describe-map-of-repeated-string
|
||||
type Licenses struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -148,7 +147,7 @@ type ScanOptions struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
VulnType []string `protobuf:"bytes,1,rep,name=vuln_type,json=vulnType,proto3" json:"vuln_type,omitempty"`
|
||||
SecurityChecks []string `protobuf:"bytes,2,rep,name=security_checks,json=securityChecks,proto3" json:"security_checks,omitempty"`
|
||||
Scanners []string `protobuf:"bytes,2,rep,name=scanners,proto3" json:"scanners,omitempty"`
|
||||
ListAllPackages bool `protobuf:"varint,3,opt,name=list_all_packages,json=listAllPackages,proto3" json:"list_all_packages,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"`
|
||||
}
|
||||
@@ -192,9 +191,9 @@ func (x *ScanOptions) GetVulnType() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ScanOptions) GetSecurityChecks() []string {
|
||||
func (x *ScanOptions) GetScanners() []string {
|
||||
if x != nil {
|
||||
return x.SecurityChecks
|
||||
return x.Scanners
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -391,69 +390,68 @@ 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, 0xc6, 0x02, 0x0a, 0x0b, 0x53, 0x63, 0x61, 0x6e, 0x4f,
|
||||
0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb9, 0x02, 0x0a, 0x0b, 0x53, 0x63, 0x61, 0x6e, 0x4f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x75, 0x6c, 0x6e, 0x5f, 0x74,
|
||||
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x76, 0x75, 0x6c, 0x6e, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f,
|
||||
0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65,
|
||||
0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x2a, 0x0a, 0x11,
|
||||
0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
|
||||
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c,
|
||||
0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x63, 0x0a, 0x12, 0x6c, 0x69, 0x63, 0x65,
|
||||
0x6e, 0x73, 0x65, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e, 0x73, 0x63, 0x61,
|
||||
0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x4f, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67,
|
||||
0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6c, 0x69, 0x63, 0x65,
|
||||
0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 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, 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, 0x9a, 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, 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,
|
||||
0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18,
|
||||
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12,
|
||||
0x2a, 0x0a, 0x11, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x63, 0x6b,
|
||||
0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6c, 0x69, 0x73, 0x74,
|
||||
0x41, 0x6c, 0x6c, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x12, 0x63, 0x0a, 0x12, 0x6c,
|
||||
0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65,
|
||||
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x72, 0x69, 0x76, 0x79, 0x2e,
|
||||
0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x4f,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61,
|
||||
0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6c,
|
||||
0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 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, 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, 0x9a, 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, 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 (
|
||||
|
||||
@@ -24,7 +24,7 @@ message Licenses {
|
||||
|
||||
message ScanOptions {
|
||||
repeated string vuln_type = 1;
|
||||
repeated string security_checks = 2;
|
||||
repeated string scanners = 2;
|
||||
bool list_all_packages = 3;
|
||||
map<string, Licenses> license_categories = 4;
|
||||
}
|
||||
|
||||
@@ -3,38 +3,24 @@
|
||||
|
||||
package scanner
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
import context "context"
|
||||
import fmt "fmt"
|
||||
import http "net/http"
|
||||
import ioutil "io/ioutil"
|
||||
import json "encoding/json"
|
||||
import strconv "strconv"
|
||||
import strings "strings"
|
||||
|
||||
http "net/http"
|
||||
import protojson "google.golang.org/protobuf/encoding/protojson"
|
||||
import proto "google.golang.org/protobuf/proto"
|
||||
import twirp "github.com/twitchtv/twirp"
|
||||
import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
|
||||
|
||||
ioutil "io/ioutil"
|
||||
|
||||
json "encoding/json"
|
||||
|
||||
strconv "strconv"
|
||||
|
||||
strings "strings"
|
||||
|
||||
protojson "google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
|
||||
twirp "github.com/twitchtv/twirp"
|
||||
|
||||
ctxsetters "github.com/twitchtv/twirp/ctxsetters"
|
||||
|
||||
bytes "bytes"
|
||||
|
||||
errors "errors"
|
||||
|
||||
io "io"
|
||||
|
||||
path "path"
|
||||
|
||||
url "net/url"
|
||||
)
|
||||
import bytes "bytes"
|
||||
import errors "errors"
|
||||
import io "io"
|
||||
import path "path"
|
||||
import url "net/url"
|
||||
|
||||
// Version compatibility assertion.
|
||||
// If the constant is not defined in the package, that likely means
|
||||
@@ -1108,45 +1094,44 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error)
|
||||
}
|
||||
|
||||
var twirpFileDescriptor0 = []byte{
|
||||
// 630 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0x6f, 0x6f, 0xd3, 0x3e,
|
||||
0x10, 0xc7, 0xd5, 0x76, 0x6b, 0xbb, 0xcb, 0x4f, 0xbf, 0x76, 0x16, 0x4c, 0x59, 0xc7, 0x9f, 0xaa,
|
||||
0x0f, 0xa0, 0xe2, 0x41, 0xca, 0x32, 0x10, 0x08, 0x1e, 0xc1, 0x18, 0x68, 0x12, 0x68, 0x93, 0x3b,
|
||||
0xf1, 0x80, 0x27, 0xc1, 0x75, 0x6e, 0x9d, 0xb5, 0x34, 0xce, 0x6c, 0xa7, 0x52, 0xde, 0xca, 0x5e,
|
||||
0x10, 0xaf, 0x0b, 0xd9, 0x49, 0xa6, 0xb5, 0xdb, 0x78, 0x14, 0xdf, 0xdd, 0xe7, 0xce, 0x67, 0xdf,
|
||||
0x37, 0x86, 0x5d, 0x95, 0xf1, 0x89, 0xe6, 0x2c, 0x4d, 0x51, 0x4d, 0x34, 0xaa, 0xa5, 0xe0, 0x18,
|
||||
0x64, 0x4a, 0x1a, 0x49, 0xfa, 0x46, 0x89, 0x65, 0x11, 0x54, 0xc1, 0x60, 0xb9, 0x3f, 0xf0, 0x2d,
|
||||
0xcc, 0xe5, 0x62, 0x21, 0xd3, 0x55, 0x76, 0x74, 0xdd, 0x00, 0x6f, 0xca, 0x59, 0x4a, 0xf1, 0x2a,
|
||||
0x47, 0x6d, 0xc8, 0x0e, 0xb4, 0x0d, 0x53, 0x73, 0x34, 0x7e, 0x63, 0xd8, 0x18, 0x6f, 0xd1, 0xca,
|
||||
0x22, 0xcf, 0xc1, 0x63, 0xca, 0x88, 0x73, 0xc6, 0x4d, 0x24, 0x62, 0xbf, 0xe9, 0x82, 0x50, 0xbb,
|
||||
0x8e, 0x63, 0xb2, 0x0b, 0xdd, 0x59, 0x22, 0x67, 0x91, 0x88, 0xb5, 0xdf, 0x1a, 0xb6, 0xc6, 0x5b,
|
||||
0xb4, 0x63, 0xed, 0xe3, 0x58, 0x93, 0x77, 0xd0, 0x91, 0x99, 0x11, 0x32, 0xd5, 0xfe, 0xc6, 0xb0,
|
||||
0x31, 0xf6, 0xc2, 0xa7, 0xc1, 0x7a, 0x87, 0x81, 0xed, 0xe1, 0xa4, 0x84, 0x68, 0x4d, 0x8f, 0x86,
|
||||
0xd0, 0xfd, 0x2e, 0x38, 0xa6, 0x1a, 0x35, 0x79, 0x04, 0x9b, 0x29, 0x5b, 0xa0, 0xf6, 0x1b, 0xae,
|
||||
0x78, 0x69, 0x8c, 0xfe, 0x34, 0xcb, 0xf6, 0xab, 0x54, 0xb2, 0x07, 0x5b, 0xcb, 0x3c, 0x49, 0x23,
|
||||
0x53, 0x64, 0x58, 0x91, 0x5d, 0xeb, 0x38, 0x2b, 0x32, 0x24, 0x2f, 0xa1, 0xa7, 0x91, 0xe7, 0x4a,
|
||||
0x98, 0x22, 0xe2, 0x17, 0xc8, 0x2f, 0xb5, 0xdf, 0x74, 0xc8, 0xff, 0xb5, 0xfb, 0xd0, 0x79, 0xc9,
|
||||
0x2b, 0xd8, 0x4e, 0x84, 0x36, 0x11, 0x4b, 0x92, 0x28, 0x63, 0xfc, 0x92, 0xcd, 0xd1, 0x1e, 0xaa,
|
||||
0x31, 0xee, 0xd2, 0x9e, 0x0d, 0x7c, 0x4a, 0x92, 0xd3, 0xca, 0x4d, 0x38, 0x90, 0xa4, 0xec, 0x31,
|
||||
0xe2, 0xcc, 0xe0, 0x5c, 0x2a, 0x81, 0xf6, 0x9c, 0xad, 0xb1, 0x17, 0xbe, 0xf9, 0xe7, 0x39, 0x83,
|
||||
0xea, 0x6c, 0x87, 0x37, 0x69, 0x47, 0xa9, 0x51, 0x05, 0xdd, 0x4e, 0xd6, 0xfd, 0x83, 0xdf, 0xb0,
|
||||
0x73, 0x3f, 0x4c, 0xfa, 0xd0, 0xba, 0xc4, 0xa2, 0x1a, 0x96, 0x5d, 0x92, 0xd7, 0xb0, 0xb9, 0x64,
|
||||
0x49, 0x8e, 0x6e, 0x46, 0x5e, 0x38, 0xb8, 0xdb, 0x43, 0x7d, 0xa7, 0xb4, 0x04, 0x3f, 0x34, 0xdf,
|
||||
0x37, 0x46, 0x31, 0xfc, 0x57, 0xca, 0x40, 0x67, 0x32, 0xd5, 0x48, 0x86, 0xd0, 0x94, 0xda, 0x95,
|
||||
0xf5, 0xc2, 0x7e, 0x55, 0xa2, 0x14, 0x50, 0x70, 0x32, 0xa5, 0x4d, 0xa9, 0x49, 0x08, 0x1d, 0x85,
|
||||
0x3a, 0x4f, 0x4c, 0x39, 0x6f, 0x2f, 0xf4, 0xef, 0xee, 0x44, 0x1d, 0x40, 0x6b, 0x70, 0x74, 0xdd,
|
||||
0x82, 0x76, 0xe9, 0x7b, 0x50, 0x68, 0x47, 0xd0, 0xb3, 0x03, 0x43, 0xc5, 0x66, 0x22, 0x11, 0xc6,
|
||||
0x5e, 0x66, 0xd3, 0x95, 0xdf, 0x5b, 0xed, 0xe2, 0xe7, 0x2d, 0xa8, 0xa0, 0xeb, 0x39, 0xe4, 0x0c,
|
||||
0xb6, 0x17, 0x42, 0x73, 0x99, 0x9e, 0x8b, 0x79, 0xae, 0x58, 0xad, 0x3e, 0x5b, 0xe8, 0xc5, 0x6a,
|
||||
0xa1, 0x2f, 0x68, 0x90, 0x1b, 0x8c, 0x7f, 0xac, 0xe1, 0xf4, 0x6e, 0x01, 0x2b, 0x42, 0x9e, 0x30,
|
||||
0xad, 0xfd, 0xb6, 0xeb, 0xb9, 0x34, 0x08, 0x81, 0x0d, 0xa7, 0xb7, 0x96, 0x73, 0xba, 0x35, 0xd9,
|
||||
0x87, 0xee, 0x8d, 0x72, 0x36, 0xdd, 0xb6, 0x8f, 0x57, 0xb7, 0xad, 0x04, 0x44, 0x6f, 0x30, 0xf2,
|
||||
0x0d, 0xfa, 0x3c, 0xd7, 0x46, 0x2e, 0x22, 0x85, 0x5a, 0xe6, 0x8a, 0xa3, 0xf6, 0x3b, 0x2e, 0xf5,
|
||||
0xc9, 0x6a, 0xea, 0xa1, 0xa3, 0x68, 0x05, 0xd1, 0x1e, 0x5f, 0xb1, 0x35, 0x79, 0x0b, 0x1d, 0x8d,
|
||||
0x5c, 0xa1, 0xd1, 0x7e, 0xf7, 0xbe, 0xab, 0x9b, 0xba, 0xe0, 0x57, 0x91, 0xc6, 0x22, 0x9d, 0xd3,
|
||||
0x9a, 0x0d, 0x4f, 0xa1, 0x33, 0x2d, 0x47, 0x47, 0x8e, 0x60, 0xc3, 0x2e, 0xc9, 0x03, 0x3f, 0x6a,
|
||||
0xf5, 0x58, 0x0c, 0x9e, 0x3d, 0x14, 0x2e, 0x45, 0xf4, 0xf9, 0xe0, 0xd7, 0xfe, 0x5c, 0x98, 0x8b,
|
||||
0x7c, 0x66, 0x77, 0x9e, 0xb0, 0xab, 0x9c, 0xd5, 0x3f, 0xda, 0xc4, 0x25, 0x4e, 0x6e, 0xbd, 0x61,
|
||||
0x1f, 0xab, 0xef, 0xac, 0xed, 0x1e, 0xa6, 0x83, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xdf,
|
||||
0x7a, 0xaf, 0xe1, 0x04, 0x00, 0x00,
|
||||
// 617 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0x5f, 0x6f, 0xd3, 0x30,
|
||||
0x10, 0xc0, 0xd5, 0x76, 0x6b, 0xb3, 0x0b, 0xd2, 0x3a, 0x0b, 0xa6, 0xac, 0xe3, 0x4f, 0xd5, 0x07,
|
||||
0x54, 0xf1, 0x90, 0xb2, 0x0c, 0x04, 0x82, 0x27, 0x18, 0x03, 0x4d, 0x02, 0x6d, 0x72, 0x27, 0x1e,
|
||||
0x78, 0x09, 0xae, 0x73, 0x2b, 0xd6, 0xd2, 0x38, 0xb3, 0x9d, 0x4a, 0xf9, 0x2a, 0xfb, 0x26, 0x7c,
|
||||
0x3b, 0x64, 0x27, 0x99, 0xd6, 0x6e, 0xe3, 0x29, 0xbe, 0xbb, 0xdf, 0xfd, 0xf3, 0x5d, 0x0c, 0x7b,
|
||||
0x2a, 0xe7, 0x13, 0xcd, 0x59, 0x96, 0xa1, 0x9a, 0x68, 0x54, 0x4b, 0xc1, 0x31, 0xcc, 0x95, 0x34,
|
||||
0x92, 0xf4, 0x8d, 0x12, 0xcb, 0x32, 0xac, 0x8d, 0xe1, 0xf2, 0x60, 0x10, 0x58, 0x98, 0xcb, 0xc5,
|
||||
0x42, 0x66, 0xab, 0xec, 0xe8, 0xba, 0x05, 0xfe, 0x94, 0xb3, 0x8c, 0xe2, 0x55, 0x81, 0xda, 0x90,
|
||||
0x5d, 0xe8, 0x1a, 0xa6, 0xe6, 0x68, 0x82, 0xd6, 0xb0, 0x35, 0xde, 0xa2, 0xb5, 0x44, 0x5e, 0x80,
|
||||
0xcf, 0x94, 0x11, 0x17, 0x8c, 0x9b, 0x58, 0x24, 0x41, 0xdb, 0x19, 0xa1, 0x51, 0x9d, 0x24, 0x64,
|
||||
0x0f, 0xbc, 0x59, 0x2a, 0x67, 0xb1, 0x48, 0x74, 0xd0, 0x19, 0x76, 0xc6, 0x5b, 0xb4, 0x67, 0xe5,
|
||||
0x93, 0x44, 0x93, 0x77, 0xd0, 0x93, 0xb9, 0x11, 0x32, 0xd3, 0xc1, 0xc6, 0xb0, 0x35, 0xf6, 0xa3,
|
||||
0x67, 0xe1, 0x7a, 0x85, 0xa1, 0xad, 0xe1, 0xb4, 0x82, 0x68, 0x43, 0x8f, 0x86, 0xe0, 0x7d, 0x17,
|
||||
0x1c, 0x33, 0x8d, 0x9a, 0x3c, 0x86, 0xcd, 0x8c, 0x2d, 0x50, 0x07, 0x2d, 0x17, 0xbc, 0x12, 0x46,
|
||||
0x7f, 0xdb, 0x55, 0xf9, 0xb5, 0x2b, 0xd9, 0x87, 0xad, 0x65, 0x91, 0x66, 0xb1, 0x29, 0x73, 0xac,
|
||||
0x49, 0xcf, 0x2a, 0xce, 0xcb, 0x1c, 0xc9, 0x00, 0xbc, 0x3a, 0xa3, 0x0e, 0xda, 0x95, 0xad, 0x91,
|
||||
0xc9, 0x2b, 0xd8, 0x49, 0x85, 0x36, 0x31, 0x4b, 0xd3, 0x38, 0x67, 0xfc, 0x92, 0xcd, 0xd1, 0xf6,
|
||||
0xd1, 0x1a, 0x7b, 0x74, 0xdb, 0x1a, 0x3e, 0xa5, 0xe9, 0x59, 0xad, 0x26, 0x1c, 0x48, 0x5a, 0x95,
|
||||
0x15, 0x73, 0x66, 0x70, 0x2e, 0x95, 0x40, 0xdb, 0x5a, 0x67, 0xec, 0x47, 0x6f, 0xfe, 0xdb, 0x5a,
|
||||
0x58, 0xb7, 0x73, 0x74, 0xe3, 0x76, 0x9c, 0x19, 0x55, 0xd2, 0x9d, 0x74, 0x5d, 0x3f, 0xf8, 0x0d,
|
||||
0xbb, 0xf7, 0xc3, 0xa4, 0x0f, 0x9d, 0x4b, 0x2c, 0xeb, 0xf9, 0xd8, 0x23, 0x79, 0x0d, 0x9b, 0x4b,
|
||||
0x96, 0x16, 0xe8, 0xc6, 0xe2, 0x47, 0x83, 0xbb, 0x35, 0x34, 0xd7, 0x48, 0x2b, 0xf0, 0x43, 0xfb,
|
||||
0x7d, 0x6b, 0x94, 0xc0, 0xa3, 0x6a, 0xf2, 0x3a, 0x97, 0x99, 0x46, 0x32, 0x84, 0xb6, 0xd4, 0x2e,
|
||||
0xac, 0x1f, 0xf5, 0xeb, 0x10, 0xd5, 0xce, 0x84, 0xa7, 0x53, 0xda, 0x96, 0x9a, 0x44, 0xd0, 0x53,
|
||||
0xa8, 0x8b, 0xd4, 0x54, 0x23, 0xf6, 0xa3, 0xe0, 0x6e, 0x26, 0xea, 0x00, 0xda, 0x80, 0xa3, 0xeb,
|
||||
0x0e, 0x74, 0x2b, 0xdd, 0x83, 0xbb, 0x75, 0x0c, 0xdb, 0x76, 0x46, 0xa8, 0xd8, 0x4c, 0xa4, 0xc2,
|
||||
0xd8, 0xcb, 0x6c, 0xbb, 0xf0, 0xfb, 0xab, 0x55, 0xfc, 0xbc, 0x05, 0x95, 0x74, 0xdd, 0x87, 0x9c,
|
||||
0xc3, 0xce, 0x42, 0x68, 0x2e, 0xb3, 0x0b, 0x31, 0x2f, 0x14, 0x6b, 0x16, 0xce, 0x06, 0x7a, 0xb9,
|
||||
0x1a, 0xe8, 0x0b, 0x1a, 0xe4, 0x06, 0x93, 0x1f, 0x6b, 0x38, 0xbd, 0x1b, 0xc0, 0xee, 0x1d, 0x4f,
|
||||
0x99, 0xd6, 0x41, 0xd7, 0xd5, 0x5c, 0x09, 0x84, 0xc0, 0x86, 0x5b, 0xb1, 0x8e, 0x53, 0xba, 0x33,
|
||||
0x39, 0x00, 0xef, 0x66, 0x73, 0x36, 0x5d, 0xda, 0x27, 0xab, 0x69, 0xeb, 0x05, 0xa2, 0x37, 0x18,
|
||||
0xf9, 0x06, 0x7d, 0x5e, 0x68, 0x23, 0x17, 0xb1, 0x42, 0x2d, 0x0b, 0xc5, 0x51, 0x07, 0x3d, 0xe7,
|
||||
0xfa, 0x74, 0xd5, 0xf5, 0xc8, 0x51, 0xb4, 0x86, 0xe8, 0x36, 0x5f, 0x91, 0x35, 0x79, 0x0b, 0x3d,
|
||||
0x8d, 0x5c, 0xa1, 0xd1, 0x81, 0x77, 0xdf, 0xd5, 0x4d, 0x9d, 0xf1, 0xab, 0xc8, 0x12, 0x91, 0xcd,
|
||||
0x69, 0xc3, 0x46, 0x67, 0xd0, 0x9b, 0x56, 0xa3, 0x23, 0xc7, 0xb0, 0x61, 0x8f, 0xe4, 0x81, 0x7f,
|
||||
0xb3, 0x7e, 0x1f, 0x06, 0xcf, 0x1f, 0x32, 0x57, 0x4b, 0xf4, 0xf9, 0xf0, 0xd7, 0xc1, 0x5c, 0x98,
|
||||
0x3f, 0xc5, 0xcc, 0x66, 0x9e, 0xb0, 0xab, 0x82, 0x69, 0xe4, 0x85, 0x12, 0xa6, 0x9c, 0x38, 0xc7,
|
||||
0xc9, 0xad, 0x67, 0xeb, 0x63, 0xfd, 0x9d, 0x75, 0xdd, 0x5b, 0x74, 0xf8, 0x2f, 0x00, 0x00, 0xff,
|
||||
0xff, 0x18, 0xc4, 0x97, 0x86, 0xd4, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user