feat(command): add rootfs command (#1271)

This commit is contained in:
Teppei Fukuda
2021-10-05 03:03:34 +09:00
committed by GitHub
parent a463e794ce
commit 1c9ccb5e03
21 changed files with 271 additions and 134 deletions

View File

@@ -10,7 +10,7 @@ FROM alpine:3.7
RUN apk add curl \ RUN apk add curl \
&& curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \ && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \
&& trivy filesystem --exit-code 1 --no-progress / && trivy rootfs --exit-code 1 --no-progress /
$ docker build -t vulnerable-image . $ docker build -t vulnerable-image .
``` ```
@@ -21,7 +21,7 @@ insecure `curl | sh`. Also the image is not changed.
# Run vulnerability scan on build image # Run vulnerability scan on build image
FROM build AS vulnscan FROM build AS vulnscan
COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy
RUN trivy filesystem --exit-code 1 --no-progress / RUN trivy rootfs --exit-code 1 --no-progress /
[...] [...]
``` ```

View File

@@ -6,7 +6,7 @@ In this case, Trivy works the same way when scanning containers
```bash ```bash
$ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf - $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
$ trivy fs /tmp/rootfs $ trivy rootfs /tmp/rootfs
``` ```
<details> <details>

View File

@@ -10,7 +10,6 @@ USAGE:
OPTIONS: OPTIONS:
--template value, -t value output template [$TRIVY_TEMPLATE] --template value, -t value output template [$TRIVY_TEMPLATE]
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT] --format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] --severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
--output value, -o value output file name [$TRIVY_OUTPUT] --output value, -o value output file name [$TRIVY_OUTPUT]
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE] --exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
@@ -18,7 +17,6 @@ OPTIONS:
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE] --skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE] --clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED] --ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS]
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE] --vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS] --security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] --ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]

View File

@@ -0,0 +1,34 @@
# Rootfs
```bash
NAME:
trivy rootfs - scan rootfs
USAGE:
trivy rootfs [command options] dir
OPTIONS:
--template value, -t value output template [$TRIVY_TEMPLATE]
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
--output value, -o value output file name [$TRIVY_OUTPUT]
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE]
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY]
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA]
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
--help, -h show help (default: false)
```

View File

@@ -8,7 +8,7 @@ Trivy detects two types of security issues:
Trivy can scan three different artifacts: Trivy can scan three different artifacts:
- [Container Images][container] - [Container Images][container]
- [Filesystem][filesystem] - [Filesystem][filesystem] and [Rootfs][rootfs]
- [Git Repositories][repo] - [Git Repositories][repo]
Trivy can be run in two different modes: Trivy can be run in two different modes:
@@ -53,7 +53,7 @@ See [Integrations][integrations] for details.
- A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR - A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR
- A tar archive stored in the `docker save` / `podman save` formatted file - A tar archive stored in the `docker save` / `podman save` formatted file
- An image directory compliant with [OCI Image Format][oci] - An image directory compliant with [OCI Image Format][oci]
- local filesystem - local filesystem and rootfs
- remote git repository - remote git repository
Please see [LICENSE][license] for Trivy licensing information. Please see [LICENSE][license] for Trivy licensing information.
@@ -64,6 +64,7 @@ Please see [LICENSE][license] for Trivy licensing information.
[vuln]: ../vulnerability/scanning/index.md [vuln]: ../vulnerability/scanning/index.md
[misconf]: ../misconfiguration/index.md [misconf]: ../misconfiguration/index.md
[container]: ../vulnerability/scanning/image.md [container]: ../vulnerability/scanning/image.md
[rootfs]: ../vulnerability/scanning/rootfs.md
[filesystem]: ../vulnerability/scanning/filesystem.md [filesystem]: ../vulnerability/scanning/filesystem.md
[repo]: ../vulnerability/scanning/git-repository.md [repo]: ../vulnerability/scanning/git-repository.md

View File

@@ -2,23 +2,23 @@
`Trivy` automatically detects the following files in the container and scans vulnerabilities in the application dependencies. `Trivy` automatically detects the following files in the container and scans vulnerabilities in the application dependencies.
| Language | File | Image[^6] | Filesystem[^7] | Repository[^8] |Dev dependencies | | Language | File | Image[^6] | Rootfs[^7] | Filesysetm[^8] | Repository[^9] |Dev dependencies |
|---------|-------------------------|:---------:|:--------------:|:---------------:|-----------------| |----------|--------------------------|:---------:|:----------:|:--------------:|:---------------:|-----------------|
| Ruby | Gemfile.lock | - | ✅ | ✅ | included | | Ruby | Gemfile.lock | - | - | ✅ | ✅ | included |
| | gemspec | ✅ | ✅ | - | included | | | gemspec | ✅ | ✅ | - | - | included |
| Python | Pipfile.lock | - | ✅ | ✅ | excluded | | Python | Pipfile.lock | - | - | ✅ | ✅ | excluded |
| | poetry.lock | - | ✅ | ✅ | included | | | poetry.lock | - | - | ✅ | ✅ | included |
| | requirements.txt | - | ✅ | ✅ | included | | | requirements.txt | - | - | ✅ | ✅ | included |
| | egg package[^1] | ✅ | ✅ | - | excluded | | | egg package[^1] | ✅ | ✅ | - | - | excluded |
| | wheel package[^2] | ✅ | ✅ | - | excluded | | | wheel package[^2] | ✅ | ✅ | - | - | excluded |
| PHP | composer.lock | ✅ | ✅ | ✅ | excluded | | PHP | composer.lock | ✅ | ✅ | ✅ | ✅ | excluded |
| Node.js | package-lock.json | - | ✅ | ✅ | excluded | | Node.js | package-lock.json | - | - | ✅ | ✅ | excluded |
| | yarn.lock | - | ✅ | ✅ | included | | | yarn.lock | - | - | ✅ | ✅ | included |
| | package.json | ✅ | ✅ | - | excluded | | | package.json | ✅ | ✅ | - | - | excluded |
| .NET | packages.lock.json | ✅ | ✅ | ✅ | included | | .NET | packages.lock.json | ✅ | ✅ | ✅ | ✅ | included |
| Java | JAR/WAR/EAR[^3][^4] | ✅ | ✅ | ✅ | included | | Java | JAR/WAR/EAR[^3][^4] | ✅ | ✅ | ✅ | ✅ | included |
| Go | Binaries built by Go[^5] | ✅ | ✅ | - | excluded | | Go | Binaries built by Go[^5] | ✅ | ✅ | - | - | excluded |
| | go.sum | - | ✅ | ✅ | included | | | go.sum | - | - | ✅ | ✅ | included |
The path of these files does not matter. The path of these files does not matter.
@@ -30,5 +30,6 @@ Example: [Dockerfile](https://github.com/aquasecurity/trivy-ci-test/blob/main/Do
[^4]: It requires the Internet access [^4]: It requires the Internet access
[^5]: UPX-compressed binaries don't work [^5]: UPX-compressed binaries don't work
[^6]: ✅ means "enabled" and `-` means "disabled" in the image scanning [^6]: ✅ means "enabled" and `-` means "disabled" in the image scanning
[^7]: ✅ means "enabled" and `-` means "disabled" in the filesystem scanning [^7]: ✅ means "enabled" and `-` means "disabled" in the rootfs scanning
[^8]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning [^8]: ✅ means "enabled" and `-` means "disabled" in the filesystem scanning
[^9]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning

View File

@@ -1,6 +1,6 @@
# Filesystem # Filesystem
Scan a filesystem (such as a host machine, a virtual machine image, or an unpacked container image filesystem). Scan a local project including language-specific files.
```bash ```bash
$ trivy fs /path/to/project $ trivy fs /path/to/project
@@ -47,57 +47,3 @@ Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0)
``` ```
</details> </details>
## From Inside Containers
Scan your container from inside the container.
```bash
$ docker run --rm -it alpine:3.11
/ # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
/ # trivy fs /
```
<details>
<summary>Result</summary>
```
2021-03-08T05:22:26.378Z INFO Need to update DB
2021-03-08T05:22:26.380Z INFO Downloading DB...
20.37 MiB / 20.37 MiB [-------------------------------------------------------------------------------------------------------------------------------------] 100.00% 8.24 MiB p/s 2s
2021-03-08T05:22:30.134Z INFO Detecting Alpine vulnerabilities...
2021-03-08T05:22:30.138Z INFO Trivy skips scanning programming language libraries because no supported file was detected
313430f09696 (alpine 3.11.7)
============================
Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 6, CRITICAL: 0)
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| libcrypto1.1 | CVE-2021-23839 | HIGH | 1.1.1i-r0 | 1.1.1j-r0 | openssl: incorrect SSLv2 |
| | | | | | rollback protection |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23840 | | | | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23841 | | | | openssl: NULL pointer dereference |
| | | | | | in X509_issuer_and_serial_hash() |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 |
+--------------+------------------+ + + +---------------------------------------+
| libssl1.1 | CVE-2021-23839 | | | | openssl: incorrect SSLv2 |
| | | | | | rollback protection |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23840 | | | | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23841 | | | | openssl: NULL pointer dereference |
| | | | | | in X509_issuer_and_serial_hash() |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
```
</details>

View File

@@ -1,10 +1,11 @@
# Vulnerability Scanning # Vulnerability Scanning
Trivy scans [Container Images][image], [Filesystem][fs], and [Git Repositories][repo] to detect vulnerabilities. Trivy scans [Container Images][image], [Rootfs][rootfs], [Filesystem][fs], and [Git Repositories][repo] to detect vulnerabilities.
![vulnerability][vuln] ![vulnerability][vuln]
[image]: image.md [image]: image.md
[rootfs]: rootfs.md
[fs]: filesystem.md [fs]: filesystem.md
[repo]: git-repository.md [repo]: git-repository.md
[vuln]: ../../imgs/vulnerability.png [vuln]: ../../imgs/vulnerability.png

View File

@@ -0,0 +1,68 @@
# Rootfs
Scan a root filesystem (such as a host machine, a virtual machine image, or an unpacked container image filesystem).
```bash
$ trivy rootfs /path/to/rootfs
```
## From Inside Containers
Scan your container from inside the container.
```bash
$ docker run --rm -it alpine:3.11
/ # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
/ # trivy rootfs /
```
<details>
<summary>Result</summary>
```
2021-03-08T05:22:26.378Z INFO Need to update DB
2021-03-08T05:22:26.380Z INFO Downloading DB...
20.37 MiB / 20.37 MiB [-------------------------------------------------------------------------------------------------------------------------------------] 100.00% 8.24 MiB p/s 2s
2021-03-08T05:22:30.134Z INFO Detecting Alpine vulnerabilities...
2021-03-08T05:22:30.138Z INFO Trivy skips scanning programming language libraries because no supported file was detected
313430f09696 (alpine 3.11.7)
============================
Total: 6 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 6, CRITICAL: 0)
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| libcrypto1.1 | CVE-2021-23839 | HIGH | 1.1.1i-r0 | 1.1.1j-r0 | openssl: incorrect SSLv2 |
| | | | | | rollback protection |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23840 | | | | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23841 | | | | openssl: NULL pointer dereference |
| | | | | | in X509_issuer_and_serial_hash() |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 |
+--------------+------------------+ + + +---------------------------------------+
| libssl1.1 | CVE-2021-23839 | | | | openssl: incorrect SSLv2 |
| | | | | | rollback protection |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23839 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23840 | | | | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + + +---------------------------------------+
| | CVE-2021-23841 | | | | openssl: NULL pointer dereference |
| | | | | | in X509_issuer_and_serial_hash() |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23841 |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
```
</details>
## Other Examples
- [Embed in Dockerfile][embedding]
- [Unpacked container image filesystem][unpacked]
[embedding]: ../../advanced/container/embed-in-dockerfile.md
[unpacked]: ../../advanced/container/unpacked-filesystem.md

2
go.mod
View File

@@ -7,7 +7,7 @@ require (
github.com/Masterminds/sprig v2.22.0+incompatible github.com/Masterminds/sprig v2.22.0+incompatible
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/fanal v0.0.0-20211004103628-a3e6bd0a4c2a github.com/aquasecurity/fanal v0.0.0-20211004144717-124d5e3ef398
github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305 github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798

4
go.sum
View File

@@ -202,8 +202,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
github.com/aquasecurity/fanal v0.0.0-20211004103628-a3e6bd0a4c2a h1:hfgNXom1CQ8w4W+xGDJVjuL8gz6Rk+PGrPb5Hv8vdzM= github.com/aquasecurity/fanal v0.0.0-20211004144717-124d5e3ef398 h1:D2/7fMPN4qG54w2Baw6odXfO/Itojjl9ZWjTwegqj3A=
github.com/aquasecurity/fanal v0.0.0-20211004103628-a3e6bd0a4c2a/go.mod h1:nXdCM1C89phZEkn/sHQ6S5IjcvxdTnXLSKcftmhFodg= github.com/aquasecurity/fanal v0.0.0-20211004144717-124d5e3ef398/go.mod h1:nXdCM1C89phZEkn/sHQ6S5IjcvxdTnXLSKcftmhFodg=
github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305 h1:xsniAD6IrP+stY8tkytxE2tk8czkzSN3XaUvzoi1hCk= github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305 h1:xsniAD6IrP+stY8tkytxE2tk8czkzSN3XaUvzoi1hCk=
github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305/go.mod h1:Zc7Eo6tFl9l4XcqsWeabD7jHnXRBK/LdgZuu9GTSVLU= github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305/go.mod h1:Zc7Eo6tFl9l4XcqsWeabD7jHnXRBK/LdgZuu9GTSVLU=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=

View File

@@ -21,6 +21,7 @@ nav:
- Image: getting-started/cli/image.md - Image: getting-started/cli/image.md
- Config: getting-started/cli/config.md - Config: getting-started/cli/config.md
- Filesystem: getting-started/cli/fs.md - Filesystem: getting-started/cli/fs.md
- Rootfs: getting-started/cli/rootfs.md
- Repository: getting-started/cli/repo.md - Repository: getting-started/cli/repo.md
- Client: getting-started/cli/client.md - Client: getting-started/cli/client.md
- Server: getting-started/cli/server.md - Server: getting-started/cli/server.md
@@ -29,6 +30,7 @@ nav:
- Overview: vulnerability/scanning/index.md - Overview: vulnerability/scanning/index.md
- Container Image: vulnerability/scanning/image.md - Container Image: vulnerability/scanning/image.md
- Filesystem: vulnerability/scanning/filesystem.md - Filesystem: vulnerability/scanning/filesystem.md
- Rootfs: vulnerability/scanning/rootfs.md
- Git Repository: vulnerability/scanning/git-repository.md - Git Repository: vulnerability/scanning/git-repository.md
- Detection: - Detection:
- OS Packages: vulnerability/detection/os.md - OS Packages: vulnerability/detection/os.md

View File

@@ -333,6 +333,7 @@ func NewApp(version string) *cli.App {
app.Commands = []*cli.Command{ app.Commands = []*cli.Command{
NewImageCommand(), NewImageCommand(),
NewFilesystemCommand(), NewFilesystemCommand(),
NewRootfsCommand(),
NewRepositoryCommand(), NewRepositoryCommand(),
NewClientCommand(), NewClientCommand(),
NewServerCommand(), NewServerCommand(),
@@ -444,12 +445,11 @@ func NewFilesystemCommand() *cli.Command {
Name: "filesystem", Name: "filesystem",
Aliases: []string{"fs"}, Aliases: []string{"fs"},
ArgsUsage: "dir", ArgsUsage: "dir",
Usage: "scan local filesystem", Usage: "scan local filesystem for language-specific dependencies and config files",
Action: artifact.FilesystemRun, Action: artifact.FilesystemRun,
Flags: []cli.Flag{ Flags: []cli.Flag{
&templateFlag, &templateFlag,
&formatFlag, &formatFlag,
&inputFlag,
&severityFlag, &severityFlag,
&outputFlag, &outputFlag,
&exitCodeFlag, &exitCodeFlag,
@@ -457,7 +457,40 @@ func NewFilesystemCommand() *cli.Command {
&skipPolicyUpdateFlag, &skipPolicyUpdateFlag,
&clearCacheFlag, &clearCacheFlag,
&ignoreUnfixedFlag, &ignoreUnfixedFlag,
&removedPkgsFlag, &vulnTypeFlag,
&securityChecksFlag,
&ignoreFileFlag,
&cacheBackendFlag,
&timeoutFlag,
&noProgressFlag,
&ignorePolicy,
&listAllPackages,
stringSliceFlag(skipFiles),
stringSliceFlag(skipDirs),
stringSliceFlag(configPolicy),
stringSliceFlag(configData),
stringSliceFlag(policyNamespaces),
},
}
}
// NewRootfsCommand is the factory method to add filesystem command
func NewRootfsCommand() *cli.Command {
return &cli.Command{
Name: "rootfs",
ArgsUsage: "dir",
Usage: "scan rootfs",
Action: artifact.RootfsRun,
Flags: []cli.Flag{
&templateFlag,
&formatFlag,
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipDBUpdateFlag,
&skipPolicyUpdateFlag,
&clearCacheFlag,
&ignoreUnfixedFlag,
&vulnTypeFlag, &vulnTypeFlag,
&securityChecksFlag, &securityChecksFlag,
&ignoreFileFlag, &ignoreFileFlag,

View File

@@ -4,20 +4,19 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
// ConfigRun runs scan on config files // ConfigRun runs scan on config files
func ConfigRun(ctx *cli.Context) error { func ConfigRun(ctx *cli.Context) error {
opt, err := NewOption(ctx) opt, err := initOption(ctx)
if err != nil { if err != nil {
return xerrors.Errorf("option error: %w", err) return xerrors.Errorf("option error: %w", err)
} }
// initialize options // Disable OS and language analyzers
if err = opt.Init(); err != nil { opt.DisabledAnalyzers = append(analyzer.TypeOSes, analyzer.TypeLanguages...)
return xerrors.Errorf("failed to initialize options: %w", err)
}
// Scan only config files // Scan only config files
opt.VulnType = nil opt.VulnType = nil

View File

@@ -7,6 +7,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/fanal/artifact" "github.com/aquasecurity/fanal/artifact"
"github.com/aquasecurity/fanal/cache" "github.com/aquasecurity/fanal/cache"
@@ -22,17 +23,28 @@ func filesystemScanner(ctx context.Context, dir string, ac cache.ArtifactCache,
return s, cleanup, nil return s, cleanup, nil
} }
// FilesystemRun runs scan on filesystem // FilesystemRun runs scan on filesystem for language-specific dependencies and config files
func FilesystemRun(ctx *cli.Context) error { func FilesystemRun(ctx *cli.Context) error {
opt, err := NewOption(ctx) opt, err := initOption(ctx)
if err != nil { if err != nil {
return xerrors.Errorf("option error: %w", err) return xerrors.Errorf("option error: %w", err)
} }
// initialize options // Disable the individual package scanning
if err = opt.Init(); err != nil { opt.DisabledAnalyzers = analyzer.TypeIndividualPkgs
return xerrors.Errorf("failed to initialize options: %w", err)
} return Run(ctx.Context, opt, filesystemScanner, initFSCache)
}
// RootfsRun runs scan on rootfs.
func RootfsRun(ctx *cli.Context) error {
opt, err := initOption(ctx)
if err != nil {
return xerrors.Errorf("option error: %w", err)
}
// Disable the lock file scanning
opt.DisabledAnalyzers = analyzer.TypeLockfiles
return Run(ctx.Context, opt, filesystemScanner, initFSCache) return Run(ctx.Context, opt, filesystemScanner, initFSCache)
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/fanal/artifact" "github.com/aquasecurity/fanal/artifact"
"github.com/aquasecurity/fanal/cache" "github.com/aquasecurity/fanal/cache"
@@ -33,15 +34,13 @@ func dockerScanner(ctx context.Context, imageName string, ac cache.ArtifactCache
// ImageRun runs scan on docker image // ImageRun runs scan on docker image
func ImageRun(ctx *cli.Context) error { func ImageRun(ctx *cli.Context) error {
opt, err := NewOption(ctx) opt, err := initOption(ctx)
if err != nil { if err != nil {
return xerrors.Errorf("option error: %w", err) return xerrors.Errorf("option error: %w", err)
} }
// initialize options // Disable the lock file scanning
if err = opt.Init(); err != nil { opt.DisabledAnalyzers = analyzer.TypeLockfiles
return xerrors.Errorf("option initialize error: %w", err)
}
if opt.Input != "" { if opt.Input != "" {
// scan tar file // scan tar file

View File

@@ -4,6 +4,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/commands/option" "github.com/aquasecurity/trivy/pkg/commands/option"
) )
@@ -16,6 +17,10 @@ type Option struct {
option.ReportOption option.ReportOption
option.CacheOption option.CacheOption
option.ConfigOption option.ConfigOption
// We don't want to allow disabled analyzers to be passed by users,
// but it differs depending on scanning modes.
DisabledAnalyzers []analyzer.Type
} }
// NewOption is the factory method to return options // NewOption is the factory method to return options

View File

@@ -7,10 +7,12 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/analyzer/config"
"github.com/aquasecurity/fanal/artifact" "github.com/aquasecurity/fanal/artifact"
"github.com/aquasecurity/fanal/cache" "github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy/pkg/scanner" "github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/types"
) )
func repositoryScanner(ctx context.Context, dir string, ac cache.ArtifactCache, lac cache.LocalArtifactCache, func repositoryScanner(ctx context.Context, dir string, ac cache.ArtifactCache, lac cache.LocalArtifactCache,
@@ -24,15 +26,16 @@ func repositoryScanner(ctx context.Context, dir string, ac cache.ArtifactCache,
// RepositoryRun runs scan on repository // RepositoryRun runs scan on repository
func RepositoryRun(ctx *cli.Context) error { func RepositoryRun(ctx *cli.Context) error {
opt, err := NewOption(ctx) opt, err := initOption(ctx)
if err != nil { if err != nil {
return xerrors.Errorf("option error: %w", err) return xerrors.Errorf("option error: %w", err)
} }
// initialize options // Do not scan OS packages
if err = opt.Init(); err != nil { opt.VulnType = []string{types.VulnTypeLibrary}
return xerrors.Errorf("failed to initialize options: %w", err)
} // Disable the OS analyzers and individual package analyzers
opt.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...)
return Run(ctx.Context, opt, repositoryScanner, initFSCache) return Run(ctx.Context, opt, repositoryScanner, initFSCache)
} }

View File

@@ -6,6 +6,7 @@ import (
"os" "os"
"time" "time"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer"
@@ -25,7 +26,7 @@ const defaultPolicyNamespace = "appshield"
var errSkipScan = errors.New("skip subsequent processes") var errSkipScan = errors.New("skip subsequent processes")
// InitializeScanner type to define initialize function signature // InitializeScanner defines the initialize function signature of scanner
type InitializeScanner func(context.Context, string, cache.ArtifactCache, cache.LocalArtifactCache, time.Duration, type InitializeScanner func(context.Context, string, cache.ArtifactCache, cache.LocalArtifactCache, time.Duration,
artifact.Option, config.ScannerOption) (scanner.Scanner, func(), error) artifact.Option, config.ScannerOption) (scanner.Scanner, func(), error)
@@ -134,6 +135,38 @@ func initDB(c Option) error {
return nil return nil
} }
func initOption(ctx *cli.Context) (Option, error) {
opt, err := NewOption(ctx)
if err != nil {
return Option{}, xerrors.Errorf("option error: %w", err)
}
// initialize options
if err = opt.Init(); err != nil {
return Option{}, xerrors.Errorf("option initialize error: %w", err)
}
return opt, nil
}
func disabledAnalyzers(opt Option) []analyzer.Type {
// Specified analyzers to be disabled depending on scanning modes
// e.g. The 'image' subcommand should disable the lock file scanning.
analyzers := opt.DisabledAnalyzers
// It doesn't analyze apk commands by default.
if !opt.ScanRemovedPkgs {
analyzers = append(analyzers, analyzer.TypeApkCommand)
}
// Don't analyze programming language packages when not running in 'library' mode
if !utils.StringInSlice(types.VulnTypeLibrary, opt.VulnType) {
analyzers = append(analyzers, analyzer.TypeLanguages...)
}
return analyzers
}
func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner, cacheClient cache.Cache) ( func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner, cacheClient cache.Cache) (
pkgReport.Report, error) { pkgReport.Report, error) {
target := opt.Target target := opt.Target
@@ -149,17 +182,6 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
} }
log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType) log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType)
// It doesn't analyze apk commands by default.
disabledAnalyzers := []analyzer.Type{analyzer.TypeApkCommand}
if opt.ScanRemovedPkgs {
disabledAnalyzers = []analyzer.Type{}
}
// Don't analyze programming language packages when not running in 'library' mode
if !utils.StringInSlice(types.VulnTypeLibrary, opt.VulnType) {
disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeLanguages...)
}
// ScannerOptions is filled only when config scanning is enabled. // ScannerOptions is filled only when config scanning is enabled.
var configScannerOptions config.ScannerOption var configScannerOptions config.ScannerOption
if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) { if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) {
@@ -178,7 +200,7 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
} }
artifactOpt := artifact.Option{ artifactOpt := artifact.Option{
DisabledAnalyzers: disabledAnalyzers, DisabledAnalyzers: disabledAnalyzers(opt),
SkipFiles: opt.SkipFiles, SkipFiles: opt.SkipFiles,
SkipDirs: opt.SkipDirs, SkipDirs: opt.SkipDirs,
} }

View File

@@ -7,6 +7,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/commands/option" "github.com/aquasecurity/trivy/pkg/commands/option"
) )
@@ -18,7 +19,10 @@ type Option struct {
option.ReportOption option.ReportOption
option.ConfigOption option.ConfigOption
ListAllPkgs bool // We don't want to allow disabled analyzers to be passed by users,
// but it differs depending on scanning modes.
DisabledAnalyzers []analyzer.Type
RemoteAddr string RemoteAddr string
token string token string
tokenHeader string tokenHeader string
@@ -40,7 +44,6 @@ func NewOption(c *cli.Context) (Option, error) {
ImageOption: option.NewImageOption(c), ImageOption: option.NewImageOption(c),
ReportOption: option.NewReportOption(c), ReportOption: option.NewReportOption(c),
ConfigOption: option.NewConfigOption(c), ConfigOption: option.NewConfigOption(c),
ListAllPkgs: c.Bool("list-all-pkgs"),
RemoteAddr: c.String("remote"), RemoteAddr: c.String("remote"),
token: c.String("token"), token: c.String("token"),
tokenHeader: c.String("token-header"), tokenHeader: c.String("token-header"),
@@ -62,11 +65,11 @@ func (c *Option) Init() (err error) {
c.CustomHeaders.Set(c.tokenHeader, c.token) c.CustomHeaders.Set(c.tokenHeader, c.token)
} }
if err := c.ReportOption.Init(c.Logger); err != nil { if err = c.ReportOption.Init(c.Logger); err != nil {
return err return err
} }
if err := c.ArtifactOption.Init(c.Context, c.Logger); err != nil { if err = c.ArtifactOption.Init(c.Context, c.Logger); err != nil {
return err return err
} }

View File

@@ -32,6 +32,9 @@ func Run(cliCtx *cli.Context) error {
ctx, cancel := context.WithTimeout(cliCtx.Context, opt.Timeout) ctx, cancel := context.WithTimeout(cliCtx.Context, opt.Timeout)
defer cancel() defer cancel()
// Disable the lock file scanning
opt.DisabledAnalyzers = analyzer.TypeLockfiles
err = runWithTimeout(ctx, opt) err = runWithTimeout(ctx, opt)
if xerrors.Is(err, context.DeadlineExceeded) { if xerrors.Is(err, context.DeadlineExceeded) {
log.Logger.Warn("Increase --timeout value") log.Logger.Warn("Increase --timeout value")
@@ -116,20 +119,27 @@ func initialize(opt *Option) error {
return nil return nil
} }
func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func(), error) { func disabledAnalyzers(opt Option) []analyzer.Type {
remoteCache := cache.NewRemoteCache(cache.RemoteURL(opt.RemoteAddr), opt.CustomHeaders) // Specified analyzers to be disabled depending on scanning modes
// e.g. The 'image' subcommand should disable the lock file scanning.
analyzers := opt.DisabledAnalyzers
// By default, apk commands are not analyzed. // It doesn't analyze apk commands by default.
disabledAnalyzers := []analyzer.Type{analyzer.TypeApkCommand} if !opt.ScanRemovedPkgs {
if opt.ScanRemovedPkgs { analyzers = append(analyzers, analyzer.TypeApkCommand)
disabledAnalyzers = []analyzer.Type{}
} }
// Don't analyze programming language packages when not running in 'library' mode // Don't analyze programming language packages when not running in 'library' mode
if !utils.StringInSlice(types.VulnTypeLibrary, opt.VulnType) { if !utils.StringInSlice(types.VulnTypeLibrary, opt.VulnType) {
disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeLanguages...) analyzers = append(analyzers, analyzer.TypeLanguages...)
} }
return analyzers
}
func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func(), error) {
remoteCache := cache.NewRemoteCache(cache.RemoteURL(opt.RemoteAddr), opt.CustomHeaders)
// ScannerOptions is filled only when config scanning is enabled. // ScannerOptions is filled only when config scanning is enabled.
var configScannerOptions config.ScannerOption var configScannerOptions config.ScannerOption
if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) { if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) {
@@ -148,7 +158,7 @@ func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func()
} }
artifactOpt := artifact.Option{ artifactOpt := artifact.Option{
DisabledAnalyzers: disabledAnalyzers, DisabledAnalyzers: disabledAnalyzers(opt),
SkipFiles: opt.SkipFiles, SkipFiles: opt.SkipFiles,
SkipDirs: opt.SkipDirs, SkipDirs: opt.SkipDirs,
} }