diff --git a/docs/advanced/container/embed-in-dockerfile.md b/docs/advanced/container/embed-in-dockerfile.md index ed13ad0d0e76..2c467b7ae999 100644 --- a/docs/advanced/container/embed-in-dockerfile.md +++ b/docs/advanced/container/embed-in-dockerfile.md @@ -10,7 +10,7 @@ FROM alpine:3.7 RUN apk add curl \ && 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 . ``` @@ -21,7 +21,7 @@ insecure `curl | sh`. Also the image is not changed. # Run vulnerability scan on build image FROM build AS vulnscan 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 / [...] ``` diff --git a/docs/advanced/container/unpacked-filesystem.md b/docs/advanced/container/unpacked-filesystem.md index 9b53b9f289df..dea1536ba91a 100644 --- a/docs/advanced/container/unpacked-filesystem.md +++ b/docs/advanced/container/unpacked-filesystem.md @@ -6,7 +6,7 @@ In this case, Trivy works the same way when scanning containers ```bash $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf - -$ trivy fs /tmp/rootfs +$ trivy rootfs /tmp/rootfs ```
diff --git a/docs/getting-started/cli/fs.md b/docs/getting-started/cli/fs.md index 6be88c84a809..8b859fd1d615 100644 --- a/docs/getting-started/cli/fs.md +++ b/docs/getting-started/cli/fs.md @@ -10,7 +10,6 @@ USAGE: OPTIONS: --template value, -t value output template [$TRIVY_TEMPLATE] --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] --output value, -o value output file name [$TRIVY_OUTPUT] --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] --clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE] --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] --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] diff --git a/docs/getting-started/cli/rootfs.md b/docs/getting-started/cli/rootfs.md new file mode 100644 index 000000000000..fe17dd2b7224 --- /dev/null +++ b/docs/getting-started/cli/rootfs.md @@ -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) +``` \ No newline at end of file diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index 51731339758d..dc15486d4946 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -8,7 +8,7 @@ Trivy detects two types of security issues: Trivy can scan three different artifacts: - [Container Images][container] -- [Filesystem][filesystem] +- [Filesystem][filesystem] and [Rootfs][rootfs] - [Git Repositories][repo] 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 tar archive stored in the `docker save` / `podman save` formatted file - An image directory compliant with [OCI Image Format][oci] - - local filesystem + - local filesystem and rootfs - remote git repository 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 [misconf]: ../misconfiguration/index.md [container]: ../vulnerability/scanning/image.md +[rootfs]: ../vulnerability/scanning/rootfs.md [filesystem]: ../vulnerability/scanning/filesystem.md [repo]: ../vulnerability/scanning/git-repository.md diff --git a/docs/vulnerability/detection/language.md b/docs/vulnerability/detection/language.md index ea57c0dd1728..1aff374298d6 100644 --- a/docs/vulnerability/detection/language.md +++ b/docs/vulnerability/detection/language.md @@ -2,23 +2,23 @@ `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 | -|---------|-------------------------|:---------:|:--------------:|:---------------:|-----------------| -| Ruby | Gemfile.lock | - | ✅ | ✅ | included | -| | gemspec | ✅ | ✅ | - | included | -| Python | Pipfile.lock | - | ✅ | ✅ | excluded | -| | poetry.lock | - | ✅ | ✅ | included | -| | requirements.txt | - | ✅ | ✅ | included | -| | egg package[^1] | ✅ | ✅ | - | excluded | -| | wheel package[^2] | ✅ | ✅ | - | excluded | -| PHP | composer.lock | ✅ | ✅ | ✅ | excluded | -| Node.js | package-lock.json | - | ✅ | ✅ | excluded | -| | yarn.lock | - | ✅ | ✅ | included | -| | package.json | ✅ | ✅ | - | excluded | -| .NET | packages.lock.json | ✅ | ✅ | ✅ | included | -| Java | JAR/WAR/EAR[^3][^4] | ✅ | ✅ | ✅ | included | -| Go | Binaries built by Go[^5] | ✅ | ✅ | - | excluded | -| | go.sum | - | ✅ | ✅ | included | +| Language | File | Image[^6] | Rootfs[^7] | Filesysetm[^8] | Repository[^9] |Dev dependencies | +|----------|--------------------------|:---------:|:----------:|:--------------:|:---------------:|-----------------| +| Ruby | Gemfile.lock | - | - | ✅ | ✅ | included | +| | gemspec | ✅ | ✅ | - | - | included | +| Python | Pipfile.lock | - | - | ✅ | ✅ | excluded | +| | poetry.lock | - | - | ✅ | ✅ | included | +| | requirements.txt | - | - | ✅ | ✅ | included | +| | egg package[^1] | ✅ | ✅ | - | - | excluded | +| | wheel package[^2] | ✅ | ✅ | - | - | excluded | +| PHP | composer.lock | ✅ | ✅ | ✅ | ✅ | excluded | +| Node.js | package-lock.json | - | - | ✅ | ✅ | excluded | +| | yarn.lock | - | - | ✅ | ✅ | included | +| | package.json | ✅ | ✅ | - | - | excluded | +| .NET | packages.lock.json | ✅ | ✅ | ✅ | ✅ | included | +| Java | JAR/WAR/EAR[^3][^4] | ✅ | ✅ | ✅ | ✅ | included | +| Go | Binaries built by Go[^5] | ✅ | ✅ | - | - | excluded | +| | go.sum | - | - | ✅ | ✅ | included | 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 [^5]: UPX-compressed binaries don't work [^6]: ✅ means "enabled" and `-` means "disabled" in the image scanning -[^7]: ✅ means "enabled" and `-` means "disabled" in the filesystem scanning -[^8]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning +[^7]: ✅ means "enabled" and `-` means "disabled" in the rootfs scanning +[^8]: ✅ means "enabled" and `-` means "disabled" in the filesystem scanning +[^9]: ✅ means "enabled" and `-` means "disabled" in the git repository scanning diff --git a/docs/vulnerability/scanning/filesystem.md b/docs/vulnerability/scanning/filesystem.md index 5c9c63552043..b16aff71bb5a 100644 --- a/docs/vulnerability/scanning/filesystem.md +++ b/docs/vulnerability/scanning/filesystem.md @@ -1,6 +1,6 @@ # 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 $ trivy fs /path/to/project @@ -47,57 +47,3 @@ Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) ```
- -## 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 / -``` - -
-Result - -``` -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 | -+--------------+------------------+----------+-------------------+---------------+---------------------------------------+ -``` - -
diff --git a/docs/vulnerability/scanning/index.md b/docs/vulnerability/scanning/index.md index e8d895925f2a..34fb52ea937e 100644 --- a/docs/vulnerability/scanning/index.md +++ b/docs/vulnerability/scanning/index.md @@ -1,10 +1,11 @@ # 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] [image]: image.md +[rootfs]: rootfs.md [fs]: filesystem.md [repo]: git-repository.md [vuln]: ../../imgs/vulnerability.png diff --git a/docs/vulnerability/scanning/rootfs.md b/docs/vulnerability/scanning/rootfs.md new file mode 100644 index 000000000000..484a0f8261b1 --- /dev/null +++ b/docs/vulnerability/scanning/rootfs.md @@ -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 / +``` + +
+Result + +``` +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 | ++--------------+------------------+----------+-------------------+---------------+---------------------------------------+ +``` + +
+ +## Other Examples +- [Embed in Dockerfile][embedding] +- [Unpacked container image filesystem][unpacked] + +[embedding]: ../../advanced/container/embed-in-dockerfile.md +[unpacked]: ../../advanced/container/unpacked-filesystem.md diff --git a/go.mod b/go.mod index a1647a844f25..1cb80f9a1769 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Masterminds/sprig v2.22.0+incompatible github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 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-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 diff --git a/go.sum b/go.sum index 852c6c28d19f..c980780a8f34 100644 --- a/go.sum +++ b/go.sum @@ -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/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/fanal v0.0.0-20211004103628-a3e6bd0a4c2a h1:hfgNXom1CQ8w4W+xGDJVjuL8gz6Rk+PGrPb5Hv8vdzM= -github.com/aquasecurity/fanal v0.0.0-20211004103628-a3e6bd0a4c2a/go.mod h1:nXdCM1C89phZEkn/sHQ6S5IjcvxdTnXLSKcftmhFodg= +github.com/aquasecurity/fanal v0.0.0-20211004144717-124d5e3ef398 h1:D2/7fMPN4qG54w2Baw6odXfO/Itojjl9ZWjTwegqj3A= +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/go.mod h1:Zc7Eo6tFl9l4XcqsWeabD7jHnXRBK/LdgZuu9GTSVLU= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= diff --git a/mkdocs.yml b/mkdocs.yml index 9d00a80fbe38..cf6a30e1b485 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - Image: getting-started/cli/image.md - Config: getting-started/cli/config.md - Filesystem: getting-started/cli/fs.md + - Rootfs: getting-started/cli/rootfs.md - Repository: getting-started/cli/repo.md - Client: getting-started/cli/client.md - Server: getting-started/cli/server.md @@ -29,6 +30,7 @@ nav: - Overview: vulnerability/scanning/index.md - Container Image: vulnerability/scanning/image.md - Filesystem: vulnerability/scanning/filesystem.md + - Rootfs: vulnerability/scanning/rootfs.md - Git Repository: vulnerability/scanning/git-repository.md - Detection: - OS Packages: vulnerability/detection/os.md diff --git a/pkg/commands/app.go b/pkg/commands/app.go index ceecffd38da9..4492e03ea5ec 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -333,6 +333,7 @@ func NewApp(version string) *cli.App { app.Commands = []*cli.Command{ NewImageCommand(), NewFilesystemCommand(), + NewRootfsCommand(), NewRepositoryCommand(), NewClientCommand(), NewServerCommand(), @@ -444,12 +445,11 @@ func NewFilesystemCommand() *cli.Command { Name: "filesystem", Aliases: []string{"fs"}, ArgsUsage: "dir", - Usage: "scan local filesystem", + Usage: "scan local filesystem for language-specific dependencies and config files", Action: artifact.FilesystemRun, Flags: []cli.Flag{ &templateFlag, &formatFlag, - &inputFlag, &severityFlag, &outputFlag, &exitCodeFlag, @@ -457,7 +457,40 @@ func NewFilesystemCommand() *cli.Command { &skipPolicyUpdateFlag, &clearCacheFlag, &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, &securityChecksFlag, &ignoreFileFlag, diff --git a/pkg/commands/artifact/config.go b/pkg/commands/artifact/config.go index 315b816721ad..a832a9b443ed 100644 --- a/pkg/commands/artifact/config.go +++ b/pkg/commands/artifact/config.go @@ -4,20 +4,19 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/types" ) // ConfigRun runs scan on config files func ConfigRun(ctx *cli.Context) error { - opt, err := NewOption(ctx) + opt, err := initOption(ctx) if err != nil { return xerrors.Errorf("option error: %w", err) } - // initialize options - if err = opt.Init(); err != nil { - return xerrors.Errorf("failed to initialize options: %w", err) - } + // Disable OS and language analyzers + opt.DisabledAnalyzers = append(analyzer.TypeOSes, analyzer.TypeLanguages...) // Scan only config files opt.VulnType = nil diff --git a/pkg/commands/artifact/fs.go b/pkg/commands/artifact/fs.go index e2e072424553..051eeded2389 100644 --- a/pkg/commands/artifact/fs.go +++ b/pkg/commands/artifact/fs.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/artifact" "github.com/aquasecurity/fanal/cache" @@ -22,17 +23,28 @@ func filesystemScanner(ctx context.Context, dir string, ac cache.ArtifactCache, 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 { - opt, err := NewOption(ctx) + opt, err := initOption(ctx) if err != nil { return xerrors.Errorf("option error: %w", err) } - // initialize options - if err = opt.Init(); err != nil { - return xerrors.Errorf("failed to initialize options: %w", err) + // Disable the individual package scanning + opt.DisabledAnalyzers = analyzer.TypeIndividualPkgs + + 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) } diff --git a/pkg/commands/artifact/image.go b/pkg/commands/artifact/image.go index e984c34ea8a4..d3614a55c90d 100644 --- a/pkg/commands/artifact/image.go +++ b/pkg/commands/artifact/image.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/artifact" "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 func ImageRun(ctx *cli.Context) error { - opt, err := NewOption(ctx) + opt, err := initOption(ctx) if err != nil { return xerrors.Errorf("option error: %w", err) } - // initialize options - if err = opt.Init(); err != nil { - return xerrors.Errorf("option initialize error: %w", err) - } + // Disable the lock file scanning + opt.DisabledAnalyzers = analyzer.TypeLockfiles if opt.Input != "" { // scan tar file diff --git a/pkg/commands/artifact/option.go b/pkg/commands/artifact/option.go index 894f39cb5a94..8076932aba5c 100644 --- a/pkg/commands/artifact/option.go +++ b/pkg/commands/artifact/option.go @@ -4,6 +4,7 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/commands/option" ) @@ -16,6 +17,10 @@ type Option struct { option.ReportOption option.CacheOption 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 diff --git a/pkg/commands/artifact/repository.go b/pkg/commands/artifact/repository.go index f15468f417bc..5464e8a9318f 100644 --- a/pkg/commands/artifact/repository.go +++ b/pkg/commands/artifact/repository.go @@ -7,10 +7,12 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/fanal/analyzer/config" "github.com/aquasecurity/fanal/artifact" "github.com/aquasecurity/fanal/cache" "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, @@ -24,15 +26,16 @@ func repositoryScanner(ctx context.Context, dir string, ac cache.ArtifactCache, // RepositoryRun runs scan on repository func RepositoryRun(ctx *cli.Context) error { - opt, err := NewOption(ctx) + opt, err := initOption(ctx) if err != nil { return xerrors.Errorf("option error: %w", err) } - // initialize options - if err = opt.Init(); err != nil { - return xerrors.Errorf("failed to initialize options: %w", err) - } + // Do not scan OS packages + opt.VulnType = []string{types.VulnTypeLibrary} + + // Disable the OS analyzers and individual package analyzers + opt.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...) return Run(ctx.Context, opt, repositoryScanner, initFSCache) } diff --git a/pkg/commands/artifact/run.go b/pkg/commands/artifact/run.go index 9f3ff005b331..b451b464911e 100644 --- a/pkg/commands/artifact/run.go +++ b/pkg/commands/artifact/run.go @@ -6,6 +6,7 @@ import ( "os" "time" + "github.com/urfave/cli/v2" "golang.org/x/xerrors" "github.com/aquasecurity/fanal/analyzer" @@ -25,7 +26,7 @@ const defaultPolicyNamespace = "appshield" 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, artifact.Option, config.ScannerOption) (scanner.Scanner, func(), error) @@ -134,6 +135,38 @@ func initDB(c Option) error { 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) ( pkgReport.Report, error) { target := opt.Target @@ -149,17 +182,6 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner, } 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. var configScannerOptions config.ScannerOption if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) { @@ -178,7 +200,7 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner, } artifactOpt := artifact.Option{ - DisabledAnalyzers: disabledAnalyzers, + DisabledAnalyzers: disabledAnalyzers(opt), SkipFiles: opt.SkipFiles, SkipDirs: opt.SkipDirs, } diff --git a/pkg/commands/client/option.go b/pkg/commands/client/option.go index a780eb84173b..d5f74f836563 100644 --- a/pkg/commands/client/option.go +++ b/pkg/commands/client/option.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/aquasecurity/fanal/analyzer" "github.com/aquasecurity/trivy/pkg/commands/option" ) @@ -18,7 +19,10 @@ type Option struct { option.ReportOption 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 token string tokenHeader string @@ -40,7 +44,6 @@ func NewOption(c *cli.Context) (Option, error) { ImageOption: option.NewImageOption(c), ReportOption: option.NewReportOption(c), ConfigOption: option.NewConfigOption(c), - ListAllPkgs: c.Bool("list-all-pkgs"), RemoteAddr: c.String("remote"), token: c.String("token"), tokenHeader: c.String("token-header"), @@ -62,11 +65,11 @@ func (c *Option) Init() (err error) { 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 } - if err := c.ArtifactOption.Init(c.Context, c.Logger); err != nil { + if err = c.ArtifactOption.Init(c.Context, c.Logger); err != nil { return err } diff --git a/pkg/commands/client/run.go b/pkg/commands/client/run.go index 1ab69d2a4afc..b301abf634a0 100644 --- a/pkg/commands/client/run.go +++ b/pkg/commands/client/run.go @@ -32,6 +32,9 @@ func Run(cliCtx *cli.Context) error { ctx, cancel := context.WithTimeout(cliCtx.Context, opt.Timeout) defer cancel() + // Disable the lock file scanning + opt.DisabledAnalyzers = analyzer.TypeLockfiles + err = runWithTimeout(ctx, opt) if xerrors.Is(err, context.DeadlineExceeded) { log.Logger.Warn("Increase --timeout value") @@ -116,20 +119,27 @@ func initialize(opt *Option) error { return nil } -func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func(), error) { - remoteCache := cache.NewRemoteCache(cache.RemoteURL(opt.RemoteAddr), opt.CustomHeaders) +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 - // By default, apk commands are not analyzed. - disabledAnalyzers := []analyzer.Type{analyzer.TypeApkCommand} - if opt.ScanRemovedPkgs { - disabledAnalyzers = []analyzer.Type{} + // 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) { - 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. var configScannerOptions config.ScannerOption if utils.StringInSlice(types.SecurityCheckConfig, opt.SecurityChecks) { @@ -148,7 +158,7 @@ func initializeScanner(ctx context.Context, opt Option) (scanner.Scanner, func() } artifactOpt := artifact.Option{ - DisabledAnalyzers: disabledAnalyzers, + DisabledAnalyzers: disabledAnalyzers(opt), SkipFiles: opt.SkipFiles, SkipDirs: opt.SkipDirs, }