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