Compare commits

..

77 Commits

Author SHA1 Message Date
afdesk
80c7b91637 fix(report): show the summary without results (#2548) 2022-07-21 14:41:51 +03:00
DmitriyLewen
07c3ac4de1 fix(cli): replace '-' to '_' for env vars (#2561) 2022-07-21 13:41:56 +03:00
Teppei Fukuda
9da45f7bbd chore: remove a test repository (#2551) 2022-07-20 14:25:12 +03:00
Teppei Fukuda
6138f57bf9 fix(license): lazy loading of classifiers (#2547) 2022-07-20 13:43:53 +03:00
DmitriyLewen
2cbe8dfebd fix: CVE-2022-1996 in Trivy (#2499)
* replace k8s.io/client-go

* update trivy-kubernetes
2022-07-20 13:43:37 +03:00
saso
e393ce1477 docs(sbom): add sbom attestation (#2527)
Co-authored-by: Teppei Fukuda <knqyf263@gmail.com>
2022-07-19 11:41:44 +03:00
MaineK00n
ae5a2d06b4 feat(rocky): set Rocky Linux 9 EOL (#2543) 2022-07-19 09:15:09 +03:00
saso
f8dd616545 docs: add attributes to the video tag to autoplay demo videos (#2538) 2022-07-18 12:39:44 +03:00
Owen Rumney
63cbbd071a fix: yaml files with non-string chart name (#2534)
Signed-off-by: Owen Rumney <owen.rumney@aquasec.com>
2022-07-18 11:04:19 +03:00
afdesk
6d015d32aa fix: skip dirs (#2530) 2022-07-18 08:32:46 +03:00
Shubham Palriwala
30c9f90bf8 feat(repo): add support for branch, commit, & tag (#2494)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-07-17 13:54:28 +03:00
afdesk
783e7cfe0c fix: remove auto configure environment variables via viper (#2526) 2022-07-16 20:32:20 +03:00
DmitriyLewen
45dae7c2cf fix: separating multiple licenses from one line in dpkg copyright files (#2508)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-07-15 14:24:25 +03:00
afdesk
469028dca5 fix: change a capital letter for plugin uninstall subcommand (#2519) 2022-07-15 07:39:15 +03:00
Jose Donizetti
ae9ba340af fix: k8s hide empty report when scanning resource (#2517)
Signed-off-by: Jose Donizetti <jdbjunior@gmail.com>
2022-07-14 10:30:01 -03:00
Teppei Fukuda
783cf6fe74 refactor: fix comments (#2516) 2022-07-14 16:11:20 +03:00
Teppei Fukuda
603825a4f9 fix: scan vendor dir (#2515) 2022-07-14 15:35:58 +03:00
Owen Rumney
a3a66df007 feat: Add support for license scanning (#2418)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
Co-authored-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
2022-07-13 22:36:41 +03:00
Teppei Fukuda
bb06f6f8cf chore: add owners for secret scanning (#2485)
Signed-off-by: knqyf263 <knqyf263@gmail.com>
2022-07-13 14:36:05 +03:00
DmitriyLewen
6b501219de fix: remove dependency-tree flag for image subcommand (#2492) 2022-07-13 14:08:54 +03:00
Jose Donizetti
57192bd5ae fix(k8s): add shorthand for k8s namespace flag (#2495)
Signed-off-by: Jose Donizetti <jdbjunior@gmail.com>
2022-07-13 14:07:25 +03:00
DmitriyLewen
9f8685c14e docs: add information about using multiple servers to troubleshooting (#2498) 2022-07-13 14:05:48 +03:00
DmitriyLewen
ed322ac666 ci: add pushing canary build images to registries (#2428) 2022-07-11 15:49:55 +03:00
dependabot[bot]
8d4dba02c9 chore(deps): bump github.com/open-policy-agent/opa from 0.41.0 to 0.42.0 (#2479)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
Co-authored-by: Teppei Fukuda <knqyf263@gmail.com>
2022-07-11 13:37:24 +03:00
afdesk
a6685b1bad feat(dotnet): add support for .Net core .deps.json files (#2487)
Co-authored-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-07-11 13:32:38 +03:00
DmitriyLewen
56265a9b98 feat(amazon): add support for 2022 version (#2429)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-07-11 11:16:06 +03:00
Prakarsh
c6f68e361d Type correction bitnami chart (#2415) 2022-07-10 20:45:53 +03:00
dependabot[bot]
6ae4b360fd chore(deps): bump github.com/owenrumney/go-sarif/v2 from 2.1.1 to 2.1.2 (#2449) 2022-07-10 20:00:28 +03:00
dependabot[bot]
6def863470 chore(deps): bump github.com/aquasecurity/table from 1.5.1 to 1.6.0 (#2446) 2022-07-10 20:00:00 +03:00
Teppei Fukuda
e98bde3396 docs: add config file and update CLI references (#2489) 2022-07-10 19:41:42 +03:00
Teppei Fukuda
736e3f11f7 feat: add support for flag groups (#2488) 2022-07-10 15:03:57 +03:00
Teppei Fukuda
5b7e0a858d refactor: move from urfave/cli to spf13/cobra (#2458)
Co-authored-by: afdesk <work@afdesk.com>
Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com>
2022-07-09 19:40:31 +03:00
Liam Galvin
7699153c66 fix: Fix secrets output not containing file/lines (#2467) 2022-07-08 16:17:21 +03:00
afdesk
a70fd758ec fix: clear output with modules (#2478) 2022-07-07 21:13:52 +03:00
dependabot[bot]
e99bf302b6 chore(deps): bump github.com/mailru/easyjson from 0.7.6 to 0.7.7 (#2448) 2022-07-07 11:18:26 +03:00
DmitriyLewen
64854fc850 docs(cbl): distroless 1.0 supported (#2473) 2022-07-07 09:06:01 +03:00
Liam Galvin
e77cfd6487 fix: Fix example dockerfile rego policy (#2460) 2022-07-05 17:46:27 +03:00
DmitriyLewen
e778ac3e21 fix(config): add helm to list of config analyzers (#2457) 2022-07-05 14:42:57 +03:00
Jose Donizetti
aedcf5b58c feat: k8s resouces scan (#2395)
Signed-off-by: Jose Donizetti <jdbjunior@gmail.com>
2022-07-04 14:26:21 -03:00
Masahiro331
5b821d3b13 feat(sbom): add cyclonedx sbom scan (#2203)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-07-03 20:03:21 +03:00
Crypt Keeper
f0720f3ce5 chore(deps): bump wazero to latest main (#2436)
also fixes a redundant close

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-03 18:52:37 +03:00
dependabot[bot]
581fe1ed55 chore(deps): bump github.com/stretchr/testify from 1.7.3 to 1.8.0 (#2444) 2022-07-03 12:26:02 +03:00
dependabot[bot]
7a4e0687fc chore(deps): bump github.com/alicebob/miniredis/v2 from 2.21.0 to 2.22.0 (#2445) 2022-07-03 11:45:28 +03:00
dependabot[bot]
422b0fc0f1 chore(deps): bump sigstore/cosign-installer from 2.3.0 to 2.4.1 (#2442) 2022-07-03 10:27:03 +03:00
dependabot[bot]
260756d5b9 chore(deps): bump actions/setup-python from 3 to 4 (#2441) 2022-07-03 10:26:42 +03:00
dependabot[bot]
9b22035967 chore(deps): bump github.com/Azure/azure-sdk-for-go (#2450) 2022-07-03 10:26:20 +03:00
afdesk
c96090ca2c docs: remove links to removed content (#2431) 2022-07-03 10:17:21 +03:00
DmitriyLewen
14be70aa51 ci: added rpm build for rhel 9 (#2437) 2022-07-03 10:15:19 +03:00
DmitriyLewen
71980feca1 fix(secret): remove space from asymmetric private key (#2434) 2022-07-03 10:14:36 +03:00
dependabot[bot]
d94df3d9be chore(deps): bump actions/cache from 3.0.2 to 3.0.4 (#2440) 2022-07-01 18:42:31 +03:00
dependabot[bot]
d213223044 chore(deps): bump helm/kind-action from 1.2.0 to 1.3.0 (#2439) 2022-07-01 18:42:08 +03:00
dependabot[bot]
8e0c537392 chore(deps): bump golang from 1.18.2 to 1.18.3 (#2438) 2022-07-01 18:41:43 +03:00
dependabot[bot]
005d0243df chore(deps): bump github.com/aws/aws-sdk-go from 1.44.25 to 1.44.46 (#2447) 2022-07-01 18:41:19 +03:00
DmitriyLewen
7de7a1f8f3 test(integration): fix golden files for debian 9 (#2435) 2022-07-01 11:21:04 +03:00
Jonathan Pulsifer
f64534651a fix(cli): fix version string in docs link when secret scanning is enabled (#2422)
Signed-off-by: Jonathan Pulsifer <jonathan@pulsifer.ca>
2022-06-30 16:58:40 +03:00
Teppei Fukuda
164094968f refactor: move CycloneDX marshaling (#2420) 2022-06-30 10:37:46 +03:00
mycodeself
6be6f74d5c docs(nodejs): add docs about pnpm support (#2423) 2022-06-30 10:33:29 +03:00
Jose Donizetti
ac2fdc87ae docs: improve k8s usage documentation (#2425)
Signed-off-by: Jose Donizetti <jdbjunior@gmail.com>
2022-06-30 10:28:52 +03:00
Liam Galvin
fe2ae8edc8 feat: Make secrets scanning output consistant (#2410) 2022-06-29 17:23:39 +03:00
DmitriyLewen
0ed39fc805 ci: create canary build after main branch changes (#1638)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-06-29 16:58:11 +03:00
afdesk
7111301fa4 fix(misconf): skip broken scans (#2396) 2022-06-29 13:35:38 +03:00
mycodeself
c36a373def feat(nodejs): add pnpm support (#2414)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-06-29 13:31:04 +03:00
Liam Galvin
e060026ec8 fix: Fix false positive for use of COS images (#2413)
Signed-off-by: Liam Galvin <liam.galvin@aquasec.com>
2022-06-29 11:03:47 +03:00
Teppei Fukuda
8d03e5af9f eliminate nerdctl dependency (#2412) 2022-06-28 21:28:59 +03:00
Guilherme Macedo
938c0d1866 Add EOL date for SUSE SLES 15.3, 15.4 and OpenSUSE 15.4 (#2403)
Signed-off-by: Guilherme Macedo <guilherme.macedo@suse.com>
2022-06-28 06:26:44 +03:00
afdesk
6e8b50ede9 fix(go): no cast to lowercase go package names (#2401) 2022-06-27 17:31:58 +03:00
Teppei Fukuda
4a197efcb2 BREAKING(sbom): change 'trivy sbom' to scan SBOM (#2408) 2022-06-27 16:42:41 +03:00
afdesk
e2c3bc4124 fix(server): hot update the db from custom repository (#2406) 2022-06-27 13:45:48 +03:00
DmitriyLewen
57ed577459 feat: added license parser for dpkg (#2381)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-06-27 13:04:53 +03:00
Erik Godding Boye
4656850c04 chore(helm): bump appVersion to latest release (#2397)
Signed-off-by: Erik Godding Boye <egboye@gmail.com>
2022-06-27 12:18:54 +03:00
Liam Galvin
c537c91d75 fix(misconf): Update defsec (v0.68.5) to fix docker rego duplicate key (#2400)
Resolves #2394

Signed-off-by: Liam Galvin <liam.galvin@aquasec.com>
2022-06-26 09:37:57 +03:00
Jose Donizetti
ee58d53fc8 feat: extract stripe publishable and secret keys (#2392) 2022-06-23 17:01:59 +03:00
chenk
776ef1a31e feat: rbac support k8s sub-command (#2339) 2022-06-23 13:49:14 +03:00
Kyriakos Georgiou
6ed789e88b feat(ruby): drop platform strings from dependency versions bundled with bundler v2 (#2390)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-06-23 10:49:05 +03:00
Anais Urlichs
bc27198d3e docs: Updating README with new CLI command (#2359) 2022-06-22 14:46:48 +03:00
Liam Galvin
4c35084f27 fix(misconf): Update defsec to v0.68.4 to resolve CF detection bug (#2383) 2022-06-22 14:02:40 +03:00
Itay Shakury
394c948130 chore: add integration label and merge security label (#2316)
* chore: add integration label and merge security label

* use the kind/security label for vulnerabilities

Co-authored-by: knqyf263 <knqyf263@gmail.com>
2022-06-22 12:11:37 +03:00
303 changed files with 17832 additions and 6953 deletions

10
.github/CODEOWNERS vendored
View File

@@ -4,6 +4,12 @@
# Helm chart # Helm chart
helm/trivy/ @krol3 helm/trivy/ @krol3
# Misconfiguration scanning
examples/misconf/ @owenrumney @liamg @knqyf263
docs/docs/misconfiguration @owenrumney @liamg @knqyf263
pkg/fanal/analyzer/config @owenrumney @liamg @knqyf263
pkg/fanal/handler/misconf @owenrumney @liamg @knqyf263
# Kubernetes scanning # Kubernetes scanning
pkg/k8s/ @josedonizetti @chen-keinan pkg/k8s/ @josedonizetti @chen-keinan @knqyf263
docs/docs/kubernetes/ @josedonizetti @chen-keinan docs/docs/kubernetes/ @josedonizetti @chen-keinan @knqyf263

59
.github/workflows/canary.yaml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Canary build
on:
push:
branches:
- 'main'
paths:
- '**.go'
- 'Dockerfile.canary'
- '.github/workflows/canary.yaml'
workflow_dispatch:
jobs:
build-binaries:
name: Build binaries
uses: ./.github/workflows/reusable-release.yaml
with:
goreleaser_config: goreleaser-canary.yml
goreleaser_options: '--snapshot --rm-dist --timeout 60m' # will not release
secrets: inherit
upload-binaries:
name: Upload binaries
needs: build-binaries # run this job after 'build-binaries' job completes
runs-on: ubuntu-latest
steps:
- name: Restore Trivy binaries from cache
uses: actions/cache@v3.0.4
with:
path: dist/
key: ${{ runner.os }}-bins-${{github.workflow}}-${{github.sha}}
# Upload artifacts
- name: Upload artifacts (trivy_Linux-64bit)
uses: actions/upload-artifact@v3
with:
name: trivy_Linux-64bit
path: dist/trivy_*_Linux-64bit.tar.gz
if-no-files-found: error
- name: Upload artifacts (trivy_Linux-ARM64)
uses: actions/upload-artifact@v3
with:
name: trivy_Linux-ARM64
path: dist/trivy_*_Linux-ARM64.tar.gz
if-no-files-found: error
- name: Upload artifacts (trivy_macOS-64bit)
uses: actions/upload-artifact@v3
with:
name: trivy_macOS-64bit
path: dist/trivy_*_macOS-64bit.tar.gz
if-no-files-found: error
- name: Upload artifacts (trivy_macOS-ARM64)
uses: actions/upload-artifact@v3
with:
name: trivy_macOS-ARM64
path: dist/trivy_*_macOS-ARM64.tar.gz
if-no-files-found: error

View File

@@ -16,7 +16,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: true persist-credentials: true
- uses: actions/setup-python@v3 - uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Install dependencies - name: Install dependencies

View File

@@ -18,7 +18,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: true persist-credentials: true
- uses: actions/setup-python@v3 - uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Install dependencies - name: Install dependencies

View File

@@ -30,14 +30,14 @@ jobs:
with: with:
version: v3.5.0 version: v3.5.0
- name: Set up python - name: Set up python
uses: actions/setup-python@v3 uses: actions/setup-python@v4
with: with:
python-version: 3.7 python-version: 3.7
- name: Setup Chart Linting - name: Setup Chart Linting
id: lint id: lint
uses: helm/chart-testing-action@dae259e86a35ff09145c0805e2d7dd3f7207064a uses: helm/chart-testing-action@dae259e86a35ff09145c0805e2d7dd3f7207064a
- name: Setup Kubernetes cluster (KIND) - name: Setup Kubernetes cluster (KIND)
uses: helm/kind-action@94729529f85113b88f4f819c17ce61382e6d8478 uses: helm/kind-action@d08cf6ff1575077dee99962540d77ce91c62387d
with: with:
version: ${{ env.KIND_VERSION }} version: ${{ env.KIND_VERSION }}
image: ${{ env.KIND_IMAGE }} image: ${{ env.KIND_IMAGE }}

View File

@@ -3,76 +3,37 @@ on:
push: push:
tags: tags:
- "v*" - "v*"
env:
GO_VERSION: "1.18"
GH_USER: "aqua-bot"
jobs: jobs:
release: release:
name: Release name: Release
uses: ./.github/workflows/reusable-release.yaml
with:
goreleaser_config: goreleaser.yml
goreleaser_options: '--rm-dist --timeout 60m'
secrets: inherit
deploy-packages:
name: Deploy rpm/dep packages
needs: release # run this job after 'release' job completes
runs-on: ubuntu-18.04 # 20.04 doesn't provide createrepo for now runs-on: ubuntu-18.04 # 20.04 doesn't provide createrepo for now
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
permissions:
id-token: write # For cosign
packages: write # For GHCR
contents: read # Not required for public repositories, but for clarity
steps: steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install rpm reprepro createrepo distro-info
- uses: sigstore/cosign-installer@536b37ec5d5b543420bdfd9b744c5965bd4d8730
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
- name: Show available Docker Buildx platforms
run: echo ${{ steps.buildx.outputs.platforms }}
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Cache Go modules
uses: actions/cache@v3.0.2 - name: Restore Trivy binaries from cache
uses: actions/cache@v3.0.4
with: with:
path: ~/go/pkg/mod path: dist/
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-bins-${{github.workflow}}-${{github.sha}}
restore-keys: |
${{ runner.os }}-go- - name: Install dependencies
- name: Login to docker.io registry run: |
uses: docker/login-action@v2 sudo apt-get -y update
with: sudo apt-get -y install rpm reprepro createrepo distro-info
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to ghcr.io registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ env.GH_USER }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ECR
uses: docker/login-action@v2
with:
registry: public.ecr.aws
username: ${{ secrets.ECR_ACCESS_KEY_ID }}
password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
- name: Generate SBOM
uses: CycloneDX/gh-gomod-generate-sbom@v1
with:
args: mod -licenses -json -output bom.json
version: ^v1
- name: Release
uses: goreleaser/goreleaser-action@v3
with:
version: v1.4.1
args: release --rm-dist --timeout 60m
env:
GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
- name: Checkout trivy-repo - name: Checkout trivy-repo
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
@@ -80,13 +41,17 @@ jobs:
path: trivy-repo path: trivy-repo
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.ORG_REPO_TOKEN }} token: ${{ secrets.ORG_REPO_TOKEN }}
- name: Setup git settings - name: Setup git settings
run: | run: |
git config --global user.email "knqyf263@gmail.com" git config --global user.email "knqyf263@gmail.com"
git config --global user.name "Teppei Fukuda" git config --global user.name "Teppei Fukuda"
- name: Create rpm repository - name: Create rpm repository
run: ci/deploy-rpm.sh run: ci/deploy-rpm.sh
- name: Import GPG key - name: Import GPG key
run: echo -e "${{ secrets.GPG_KEY }}" | gpg --import run: echo -e "${{ secrets.GPG_KEY }}" | gpg --import
- name: Create deb repository - name: Create deb repository
run: ci/deploy-deb.sh run: ci/deploy-deb.sh

109
.github/workflows/reusable-release.yaml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Reusable release
on:
workflow_call:
inputs:
goreleaser_config:
description: 'file path to GoReleaser config'
required: true
type: string
goreleaser_options:
description: 'GoReleaser options separated by spaces'
default: ''
required: false
type: string
env:
GO_VERSION: "1.18"
GH_USER: "aqua-bot"
jobs:
release:
name: Release
runs-on: ubuntu-latest
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
permissions:
id-token: write # For cosign
packages: write # For GHCR
contents: read # Not required for public repositories, but for clarity
steps:
- name: Cosign install
uses: sigstore/cosign-installer@48866aa521d8bf870604709cd43ec2f602d03ff2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2
- name: Show available Docker Buildx platforms
run: echo ${{ steps.buildx.outputs.platforms }}
- name: Login to docker.io registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to ghcr.io registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ env.GH_USER }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to ECR
uses: docker/login-action@v2
with:
registry: public.ecr.aws
username: ${{ secrets.ECR_ACCESS_KEY_ID }}
password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Generate SBOM
uses: CycloneDX/gh-gomod-generate-sbom@v1
with:
args: mod -licenses -json -output bom.json
version: ^v1
- name: GoReleaser
uses: goreleaser/goreleaser-action@v3
with:
version: v1.4.1
args: release -f=${{ inputs.goreleaser_config}} ${{ inputs.goreleaser_options}}
env:
GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
## push images to registries
## only for canary build
- name: Build and push
if: ${{ inputs.goreleaser_config == 'goreleaser-canary.yml' }}
uses: docker/build-push-action@v3
with:
platforms: linux/amd64, linux/arm64
file: ./Dockerfile.canary # path to Dockerfile
context: .
push: true
tags: |
aquasec/trivy:canary
ghcr.io/aquasecurity/trivy:canary
public.ecr.aws/aquasecurity/trivy:canary
- name: Cache Trivy binaries
uses: actions/cache@v3.0.4
with:
path: dist/
# use 'github.sha' to create a unique cache folder for each run.
# use 'github.workflow' to create a unique cache folder if some runs have same commit sha.
# e.g. build and release runs
key: ${{ runner.os }}-bins-${{github.workflow}}-${{github.sha}}

View File

@@ -18,6 +18,6 @@ jobs:
assignee: knqyf263 assignee: knqyf263
severity: CRITICAL severity: CRITICAL
skip-dirs: integration,examples skip-dirs: integration,examples
label: vulnerability label: kind/security
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -34,6 +34,7 @@ jobs:
vuln vuln
misconf misconf
secret secret
license
image image
fs fs
@@ -79,6 +80,9 @@ jobs:
cli cli
flag flag
cyclonedx
spdx
helm helm
report report

View File

@@ -28,6 +28,7 @@ jobs:
run: | run: |
go mod tidy go mod tidy
if [ -n "$(git status --porcelain)" ]; then if [ -n "$(git status --porcelain)" ]; then
echo "Run 'go mod tidy' and push it"
exit 1 exit 1
fi fi
@@ -123,7 +124,7 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: true persist-credentials: true
- uses: actions/setup-python@v3 - uses: actions/setup-python@v4
with: with:
python-version: 3.x python-version: 3.x
- name: Install dependencies - name: Install dependencies

View File

@@ -31,7 +31,6 @@ linters:
- ineffassign - ineffassign
- typecheck - typecheck
- govet - govet
- errcheck
- varcheck - varcheck
- deadcode - deadcode
- revive - revive

10
Dockerfile.canary Normal file
View File

@@ -0,0 +1,10 @@
FROM alpine:3.16.0
RUN apk --no-cache add ca-certificates git
# binaries were created with GoReleaser
# need to copy binaries from folder with correct architecture
# example architecture folder: dist/trivy_canary_build_linux_arm64/trivy
ARG TARGETARCH
COPY "dist/trivy_canary_build_linux_${TARGETARCH}/trivy" /usr/local/bin/trivy
COPY contrib/*.tpl contrib/
ENTRYPOINT ["trivy"]

View File

@@ -1,4 +1,4 @@
FROM golang:1.18.2 FROM golang:1.18.3
# Install protoc (cf. http://google.github.io/proto-lens/installing-protoc.html) # Install protoc (cf. http://google.github.io/proto-lens/installing-protoc.html)
ENV PROTOC_ZIP=protoc-3.19.4-linux-x86_64.zip ENV PROTOC_ZIP=protoc-3.19.4-linux-x86_64.zip

View File

@@ -74,7 +74,7 @@ https://user-images.githubusercontent.com/1161307/171013917-b1f37810-f434-465c-b
</details> </details>
```bash ```bash
$ trivy k8s mycluster $ trivy k8s --report summary cluster
``` ```
<details> <details>
@@ -84,6 +84,8 @@ $ trivy k8s mycluster
</details> </details>
Note that you can also receive a detailed scan, scan only a specific namespace, resource and more.
Find out more in the [Trivy Documentation][docs] - [Getting Started][getting-started] Find out more in the [Trivy Documentation][docs] - [Getting Started][getting-started]

View File

@@ -15,7 +15,7 @@ function create_rpm_repo () {
cd trivy-repo cd trivy-repo
VERSIONS=(5 6 7 8) VERSIONS=(5 6 7 8 9)
for version in ${VERSIONS[@]}; do for version in ${VERSIONS[@]}; do
echo "Processing RHEL/CentOS $version..." echo "Processing RHEL/CentOS $version..."
create_rpm_repo $version create_rpm_repo $version

View File

@@ -1,8 +1,6 @@
package main package main
import ( import (
"os"
"github.com/aquasecurity/trivy/pkg/commands" "github.com/aquasecurity/trivy/pkg/commands"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
) )
@@ -13,8 +11,7 @@ var (
func main() { func main() {
app := commands.NewApp(version) app := commands.NewApp(version)
err := app.Run(os.Args) if err := app.Execute(); err != nil {
if err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

View File

@@ -42,6 +42,7 @@ checks:
- vuln - vuln
- misconf - misconf
- secret - secret
- license
mode: mode:

View File

@@ -0,0 +1,50 @@
# SBOM attestation
[Cosign](https://github.com/sigstore/cosign) supports generating and verifying [in-toto attestations](https://github.com/in-toto/attestation). This tool enables you to sign and verify SBOM attestation.
!!! note
In the following examples, the `cosign` command will write an attestation to a target OCI registry, so you must have permission to write.
If you want to avoid writing an OCI registry and only want to see an attestation, add the `--no-upload` option to the `cosign` command.
## Sign with a local key pair
Cosign can generate key pairs and use them for signing and verification. Read more about [how to generate key pairs](https://docs.sigstore.dev/cosign/key-generation).
In the following example, Trivy generates an SBOM in the spdx format, and then Cosign attaches an attestation of the SBOM to a container image with a local key pair.
```
$ trivy image --format spdx -o predicate <IMAGE>
$ cosign attest --key /path/to/cosign.key --type spdx --predicate predicate <IMAGE>
```
Then, you can verify attestations on the image.
```
$ cosign verify-attestation --key /path/to/cosign.pub <IMAGE>
```
You can also create attestations of other formatted SBOM.
```
# spdx-json
$ trivy image --format spdx-json -o predicate <IMAGE>
$ cosign attest --key /path/to/cosign.key --type spdx --predicate predicate <IMAGE>
# cyclonedx
$ trivy image --format cyclonedx -o predicate <IMAGE>
$ cosign attest --key /path/to/cosign.key --type https://cyclonedx.org/schema --predicate predicate <IMAGE>
```
## Keyless signing
You can use Cosign to sign without keys by authenticating with an OpenID Connect protocol supported by sigstore (Google, GitHub, or Microsoft).
```
$ trivy image --format spdx -o predicate <IMAGE>
$ COSIGN_EXPERIMENTAL=1 cosign attest --type spdx --predicate predicate <IMAGE>
```
You can verify attestations.
```
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation <IMAGE>
```

View File

@@ -28,7 +28,7 @@ See [Integrations][integrations] for details.
- Comprehensive vulnerability detection - Comprehensive vulnerability detection
- [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless) - [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
- [**Language-specific packages**][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go) - [**Language-specific packages**][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, pnpm, Cargo, NuGet, Maven, and Go)
- Detect IaC misconfigurations - Detect IaC misconfigurations
- A wide variety of [built-in policies][builtin] are provided **out of the box**: - A wide variety of [built-in policies][builtin] are provided **out of the box**:
- Kubernetes - Kubernetes
@@ -63,6 +63,7 @@ See [Integrations][integrations] for details.
- [SBOM][sbom] (Software Bill of Materials) support - [SBOM][sbom] (Software Bill of Materials) support
- CycloneDX - CycloneDX
- SPDX - SPDX
- GitHub Dependency Snapshots
Please see [LICENSE][license] for Trivy licensing information. Please see [LICENSE][license] for Trivy licensing information.

View File

@@ -47,6 +47,13 @@ Scan a specific resource and get all the output:
$ trivy k8s deployment appname $ trivy k8s deployment appname
``` ```
Scan all deploys, or deploys and configmaps:
```
$ trivy k8s --report=summary deployment
$ trivy k8s --report=summary deployment,configmaps
```
If you want to pass in flags before scanning specific workloads, you will have to do it before the resource name. If you want to pass in flags before scanning specific workloads, you will have to do it before the resource name.
For example, scanning a deployment in the app namespace of your Kubernetes cluster for critical vulnerabilities would be done through the following command: For example, scanning a deployment in the app namespace of your Kubernetes cluster for critical vulnerabilities would be done through the following command:

View File

@@ -1,17 +1,14 @@
# Trivy Operator # Trivy Operator
Trivy has a native [Kubernetes Operator](operator) which continuously scans your Kubernetes cluster for security issues, and generates security reports as Kubernetes [Custom Resources](crd). It does it by watching Kubernetes for state changes and automatically triggering scans in response to changes, for example initiating a vulnerability scan when a new Pod is created. Trivy has a native [Kubernetes Operator][operator] which continuously scans your Kubernetes cluster for security issues, and generates security reports as Kubernetes [Custom Resources][crd]. It does it by watching Kubernetes for state changes and automatically triggering scans in response to changes, for example initiating a vulnerability scan when a new Pod is created.
> Kubernetes-native security toolkit. ([Documentation](https://aquasecurity.github.io/trivy-operator/latest)). > Kubernetes-native security toolkit. ([Documentation][trivy-operator]).
<figure> <figure>
<img src="./images/operator/trivy-operator-workloads.png" />
<figcaption>Workload reconcilers discover K8s controllers, manage scan jobs, and create VulnerabilityReport and ConfigAuditReport objects.</figcaption> <figcaption>Workload reconcilers discover K8s controllers, manage scan jobs, and create VulnerabilityReport and ConfigAuditReport objects.</figcaption>
</figure> </figure>
[operator]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ [operator]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
[crd]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/ [crd]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
[Starboard]: https://github.com/aquasecurity/starboard [trivy-operator]: https://aquasecurity.github.io/trivy-operator/latest
[starboard-announcement]: https://github.com/aquasecurity/starboard/discussions/1173

View File

@@ -0,0 +1,320 @@
# License Scanning
Trivy scans any container image for license files and offers an opinionated view on the risk associated with the license.
License are classified using the [Google License Classification][google-license-classification] -
- Forbidden
- Restricted
- Reciprocal
- Notice
- Permissive
- Unencumbered
- Unknown
!!! tip
Licenses that Trivy fails to recognize are classified as UNKNOWN.
As those licenses may be in violation, it is recommended to check those unknown licenses as well.
By default, Trivy scans licenses for packages installed by `apk`, `apt-get`, `dnf`, `npm`, `pip`, `gem`, etc.
To enable extended license scanning, you can use `--license-full`.
In addition to package licenses, Trivy scans source code files, Markdown documents, text files and `LICENSE` documents to identify license usage within the image or filesystem.
!!! note
The full license scanning is expensive. It takes a while.
Currently, the standard license scanning doesn't support filesystem and repository scanning.
| License scnanning | Image | Rootfs | Filesystem | Repository |
|:---------------------:|:-----:|:---------:|:----------:|:----------:|
| Standard | ✅ | ✅ | - | - |
| Full (--license-full) | ✅ | ✅ | ✅ | ✅ |
License checking classifies the identified licenses and map the classification to severity.
| Classification | Severity |
|----------------|----------|
| Forbidden | CRITICAL |
| Restricted | HIGH |
| Reciprocal | MEDIUM |
| Notice | LOW |
| Permissive | LOW |
| Unencumbered | LOW |
| Unknown | UNKNOWN |
## Quick start
This section shows how to scan license in container image and filesystem.
### Standard scanning
Specify an image name with `--security-cheks license`.
``` shell
$ trivy image --security-checks license --severity UNKNOWN,HIGH,CRITICAL alpine:3.15
2022-07-13T17:28:39.526+0300 INFO License scanning is enabled
OS Packages (license)
=====================
Total: 6 (UNKNOWN: 0, HIGH: 6, CRITICAL: 0)
┌───────────────────┬─────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├───────────────────┼─────────┼────────────────┼──────────┤
│ alpine-baselayout │ GPL-2.0 │ Restricted │ HIGH │
├───────────────────┤ │ │ │
│ apk-tools │ │ │ │
├───────────────────┤ │ │ │
│ busybox │ │ │ │
├───────────────────┤ │ │ │
│ musl-utils │ │ │ │
├───────────────────┤ │ │ │
│ scanelf │ │ │ │
├───────────────────┤ │ │ │
│ ssl_client │ │ │ │
└───────────────────┴─────────┴────────────────┴──────────┘
```
### Full scanning
Specify `--license-full`
``` shell
$ trivy image --security-checks license --severity UNKNOWN,HIGH,CRITICAL --license-full grafana/grafana
2022-07-13T17:48:40.905+0300 INFO Full license scanning is enabled
OS Packages (license)
=====================
Total: 20 (UNKNOWN: 9, HIGH: 11, CRITICAL: 0)
┌───────────────────┬───────────────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├───────────────────┼───────────────────┼────────────────┼──────────┤
│ alpine-baselayout │ GPL-2.0 │ Restricted │ HIGH │
├───────────────────┤ │ │ │
│ apk-tools │ │ │ │
├───────────────────┼───────────────────┤ │ │
│ bash │ GPL-3.0 │ │ │
├───────────────────┼───────────────────┼────────────────┼──────────┤
│ keyutils-libs │ GPL-2.0 │ Restricted │ HIGH │
│ ├───────────────────┼────────────────┼──────────┤
│ │ LGPL-2.0-or-later │ Non Standard │ UNKNOWN │
├───────────────────┼───────────────────┤ │ │
│ libaio │ LGPL-2.1-or-later │ │ │
├───────────────────┼───────────────────┼────────────────┼──────────┤
│ libcom_err │ GPL-2.0 │ Restricted │ HIGH │
│ ├───────────────────┼────────────────┼──────────┤
│ │ LGPL-2.0-or-later │ Non Standard │ UNKNOWN │
├───────────────────┼───────────────────┼────────────────┼──────────┤
│ tzdata │ Public-Domain │ Non Standard │ UNKNOWN │
└───────────────────┴───────────────────┴────────────────┴──────────┘
Loose File License(s) (license)
===============================
Total: 6 (UNKNOWN: 4, HIGH: 0, CRITICAL: 2)
┌────────────────┬──────────┬──────────────┬──────────────────────────────────────────────────────────────┐
│ Classification │ Severity │ License │ File Location │
├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
│ Forbidden │ CRITICAL │ AGPL-3.0 │ /usr/share/grafana/LICENSE │
│ │ │ │ │
│ │ │ │ │
├────────────────┼──────────┼──────────────┼──────────────────────────────────────────────────────────────┤
│ Non Standard │ UNKNOWN │ BSD-0-Clause │ /usr/share/grafana/public/build/5069.d6aae9dd11d49c741a80.j- │
│ │ │ │ s.LICENSE.txt │
│ │ │ ├──────────────────────────────────────────────────────────────┤
│ │ │ │ /usr/share/grafana/public/build/6444.d6aae9dd11d49c741a80.j- │
│ │ │ │ s.LICENSE.txt │
│ │ │ ├──────────────────────────────────────────────────────────────┤
│ │ │ │ /usr/share/grafana/public/build/7889.d6aae9dd11d49c741a80.j- │
│ │ │ │ s.LICENSE.txt │
│ │ │ ├──────────────────────────────────────────────────────────────┤
│ │ │ │ /usr/share/grafana/public/build/canvasPanel.d6aae9dd11d49c7- │
│ │ │ │ 41a80.js.LICENSE.txt │
└────────────────┴──────────┴──────────────┴──────────────────────────────────────────────────────────────┘
```
## Configuration
Trivy has number of configuration flags for use with license scanning;
### Ignored Licenses
Trivy license scanning can ignore licenses that are identified to explicitly remove them from the results using the `--ignored-licenses` flag;
```shell
$ trivy image --security-checks license --ignored-licenses MPL-2.0,MIT --severity LOW grafana/grafana:latest
2022-07-13T18:15:28.605Z INFO License scanning is enabled
OS Packages (license)
=====================
Total: 2 (HIGH: 2, CRITICAL: 0)
┌───────────────────┬─────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├───────────────────┼─────────┼────────────────┼──────────┤
│ alpine-baselayout │ GPL-2.0 │ Restricted │ HIGH │
├───────────────────┤ │ │ │
│ ssl_client │ │ │ │
└───────────────────┴─────────┴────────────────┴──────────┘
```
### Custom Classification
You can generate the default config by the `--generate-default-config` flag and customize the license classification.
For example, if you want to forbid only AGPL-3.0, you can leave it under `forbidden` and move other licenses to another classification.
```shell
$ trivy image --generate-default-config
$ vim trivy.yaml
license:
forbidden:
- AGPL-3.0
restricted:
- AGPL-1.0
- CC-BY-NC-1.0
- CC-BY-NC-2.0
- CC-BY-NC-2.5
- CC-BY-NC-3.0
- CC-BY-NC-4.0
- CC-BY-NC-ND-1.0
- CC-BY-NC-ND-2.0
- CC-BY-NC-ND-2.5
- CC-BY-NC-ND-3.0
- CC-BY-NC-ND-4.0
- CC-BY-NC-SA-1.0
- CC-BY-NC-SA-2.0
- CC-BY-NC-SA-2.5
- CC-BY-NC-SA-3.0
- CC-BY-NC-SA-4.0
- Commons-Clause
- Facebook-2-Clause
- Facebook-3-Clause
- Facebook-Examples
- WTFPL
- BCL
- CC-BY-ND-1.0
- CC-BY-ND-2.0
- CC-BY-ND-2.5
- CC-BY-ND-3.0
- CC-BY-ND-4.0
- CC-BY-SA-1.0
- CC-BY-SA-2.0
- CC-BY-SA-2.5
- CC-BY-SA-3.0
- CC-BY-SA-4.0
- GPL-1.0
- GPL-2.0
- GPL-2.0-with-autoconf-exception
- GPL-2.0-with-bison-exception
- GPL-2.0-with-classpath-exception
- GPL-2.0-with-font-exception
- GPL-2.0-with-GCC-exception
- GPL-3.0
- GPL-3.0-with-autoconf-exception
- GPL-3.0-with-GCC-exception
- LGPL-2.0
- LGPL-2.1
- LGPL-3.0
- NPL-1.0
- NPL-1.1
- OSL-1.0
- OSL-1.1
- OSL-2.0
- OSL-2.1
- OSL-3.0
- QPL-1.0
- Sleepycat
reciprocal:
- APSL-1.0
- APSL-1.1
- APSL-1.2
- APSL-2.0
- CDDL-1.0
- CDDL-1.1
- CPL-1.0
- EPL-1.0
- EPL-2.0
- FreeImage
- IPL-1.0
- MPL-1.0
- MPL-1.1
- MPL-2.0
- Ruby
notice:
- AFL-1.1
- AFL-1.2
- AFL-2.0
- AFL-2.1
- AFL-3.0
- Apache-1.0
- Apache-1.1
- Apache-2.0
- Artistic-1.0-cl8
- Artistic-1.0-Perl
- Artistic-1.0
- Artistic-2.0
- BSL-1.0
- BSD-2-Clause-FreeBSD
- BSD-2-Clause-NetBSD
- BSD-2-Clause
- BSD-3-Clause-Attribution
- BSD-3-Clause-Clear
- BSD-3-Clause-LBNL
- BSD-3-Clause
- BSD-4-Clause
- BSD-4-Clause-UC
- BSD-Protection
- CC-BY-1.0
- CC-BY-2.0
- CC-BY-2.5
- CC-BY-3.0
- CC-BY-4.0
- FTL
- ISC
- ImageMagick
- Libpng
- Lil-1.0
- Linux-OpenIB
- LPL-1.02
- LPL-1.0
- MS-PL
- MIT
- NCSA
- OpenSSL
- PHP-3.01
- PHP-3.0
- PIL
- Python-2.0
- Python-2.0-complete
- PostgreSQL
- SGI-B-1.0
- SGI-B-1.1
- SGI-B-2.0
- Unicode-DFS-2015
- Unicode-DFS-2016
- Unicode-TOU
- UPL-1.0
- W3C-19980720
- W3C-20150513
- W3C
- X11
- Xnet
- Zend-2.0
- zlib-acknowledgement
- Zlib
- ZPL-1.1
- ZPL-2.0
- ZPL-2.1
unencumbered:
- CC0-1.0
- Unlicense
- 0BSD
permissive: []
```
[google-license-classification]: https://opensource.google/documentation/reference/thirdparty/licenses

View File

@@ -1,32 +1,69 @@
# Client # Client
```bash ```bash
NAME: Usage:
trivy client - DEPRECATED client mode, use `trivy image` with `--server` option for remote scans now. [DEPRECATED] trivy client [flags] IMAGE_NAME
USAGE: Aliases:
trivy image --server value client, c
trivy client [deprecated command options] image_name Scan Flags
--offline-scan do not issue API requests to identify dependencies
--security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--skip-dirs string specify the directories where the traversal is skipped
--skip-files string specify the file paths to skip traversal
DEPRECATED OPTIONS: Report Flags
--template value, -t value output template [$TRIVY_TEMPLATE] --dependency-tree show dependency origin tree (EXPERIMENTAL)
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT] --exit-code int specify exit code when any security issues are found
--input value, -i value input file path instead of image name [$TRIVY_INPUT] -f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] --ignore-policy string specify the Rego file path to evaluate each vulnerability
--output value, -o value output file name [$TRIVY_OUTPUT] --ignorefile string specify .trivyignore file (default ".trivyignore")
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE] --list-all-pkgs enabling the option will output all packages regardless of vulnerability
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED] -o, --output string output file name
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS] --report string specify a report format for the output. (all,summary) (default "all")
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE] -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] -t, --template string output template
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY] Cache Flags
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS] --cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] --cache-ttl duration cache TTL when using redis as cache backend
--token value for authentication [$TRIVY_TOKEN] --clear-cache clear image caches without scanning
--token-header value specify a header name for token (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER] --redis-ca string redis ca file location, if using redis as cache backend
--remote value server address (default: "http://localhost:4954") [$TRIVY_REMOTE] --redis-cert string redis certificate file location, if using redis as cache backend
--custom-headers value custom headers [$TRIVY_CUSTOM_HEADERS] --redis-key string redis key file location, if using redis as cache backend
--help, -h show help (default: false)
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Client/Server Flags
--custom-headers strings custom headers in client mode
--remote string server address (default "http://localhost:4954")
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,29 +1,52 @@
# Config # Config
``` bash ``` bash
NAME: Scan config files for misconfigurations
trivy config - scan config files
USAGE: Usage:
trivy config [command options] dir trivy config [flags] DIR
Aliases:
config, conf
Scan Flags
--skip-dirs string specify the directories where the traversal is skipped
--skip-files string specify the file paths to skip traversal
Report Flags
--dependency-tree show dependency origin tree (EXPERIMENTAL)
--exit-code int specify exit code when any security issues are found
-f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
-o, --output string output file name
-s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
-t, --template string output template
Cache Flags
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
OPTIONS:
--template value, -t value output template [$TRIVY_TEMPLATE]
--format value, -f value format (table, json, sarif, 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-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
--reset remove all caches and database (default: false) [$TRIVY_RESET]
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
--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]
--policy value, --config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_POLICY]
--data value, --config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_DATA]
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
--file-patterns value specify file patterns [$TRIVY_FILE_PATTERNS]
--include-successes include successes of misconfigurations (default: false) [$TRIVY_INCLUDE_SUCCESSES]
--help, -h show help (default: false)
``` ```

View File

@@ -1,42 +1,80 @@
# Filesystem # Filesystem
```bash ```bash
NAME: Scan local filesystem
trivy filesystem - scan local filesystem for language-specific dependencies and config files
USAGE: Usage:
trivy filesystem [command options] path trivy filesystem [flags] PATH
OPTIONS: Aliases:
--template value, -t value output template [$TRIVY_TEMPLATE] filesystem, fs
--format value, -f value format (table, json, sarif, 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] Examples:
--output value, -o value output file name [$TRIVY_OUTPUT] # Scan a local project including language-specific files
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE] $ trivy fs /path/to/your_project
--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] # Scan a single file
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE] $ trivy fs ./trivy-ci-test/Pipfile.lock
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED] Scan Flags
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE] --offline-scan do not issue API requests to identify dependencies
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS] --security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] --skip-dirs string specify the directories where the traversal is skipped
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND] --skip-files string specify the file paths to skip traversal
--cache-ttl value cache TTL when using redis as cache backend (default: 0s) [$TRIVY_CACHE_TTL]
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT] Report Flags
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS] --dependency-tree show dependency origin tree (EXPERIMENTAL)
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY] --exit-code int specify exit code when any security issues are found
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS] -f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] --ignore-policy string specify the Rego file path to evaluate each vulnerability
--db-repository value OCI repository to retrieve trivy-db from (default: "ghcr.io/aquasecurity/trivy-db") [$TRIVY_DB_REPOSITORY] --ignorefile string specify .trivyignore file (default ".trivyignore")
--skip-files value specify the file paths to skip traversal (accepts multiple inputs) [$TRIVY_SKIP_FILES] --list-all-pkgs enabling the option will output all packages regardless of vulnerability
--skip-dirs value specify the directories where the traversal is skipped (accepts multiple inputs) [$TRIVY_SKIP_DIRS] -o, --output string output file name
--config-policy value specify paths to the Rego policy files directory, applying config files (accepts multiple inputs) [$TRIVY_CONFIG_POLICY] -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
--config-data value specify paths from which data for the Rego policies will be recursively loaded (accepts multiple inputs) [$TRIVY_CONFIG_DATA] -t, --template string output template
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") (accepts multiple inputs) [$TRIVY_POLICY_NAMESPACES]
--server value server address [$TRIVY_SERVER] Cache Flags
--token value for authentication in client/server mode [$TRIVY_TOKEN] --cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--token-header value specify a header name for token in client/server mode (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER] --cache-ttl duration cache TTL when using redis as cache backend
--custom-headers value custom headers in client/server mode (accepts multiple inputs) [$TRIVY_CUSTOM_HEADERS] --clear-cache clear image caches without scanning
--help, -h show help (default: false) --redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Secret Flags
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
Client/Server Flags
--custom-headers strings custom headers in client mode
--server string server address in client mode
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,43 +1,99 @@
# Image # Image
```bash ```bash
NAME: Scan a container image
trivy image - scan an image
USAGE: Usage:
trivy image [command options] image_name trivy image [flags] IMAGE_NAME
OPTIONS: Aliases:
--template value, -t value output template [$TRIVY_TEMPLATE] image, i
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
--input value, -i value input file path instead of image name [$TRIVY_INPUT] Examples:
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] # Scan a container image
--output value, -o value output file name [$TRIVY_OUTPUT] $ trivy image python:3.4-alpine
--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] # Scan a container image from a tar archive
--download-db-only download/update vulnerability database but don't run a scan (default: false) [$TRIVY_DOWNLOAD_DB_ONLY] $ trivy image --input ruby-3.1.tar
--reset remove all caches and database (default: false) [$TRIVY_RESET]
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE] # Filter by severities
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS] $ trivy image --severity HIGH,CRITICAL alpine:3.15
--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] # Ignore unfixed/unpatched vulnerabilities
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE] $ trivy image --ignore-unfixed alpine:3.15
--security-checks value comma-separated list of what security issues to detect (vuln,config,secret) (default: "vuln,secret") [$TRIVY_SECURITY_CHECKS]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] # Scan a container image in client mode
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT] $ trivy image --server http://127.0.0.1:4954 alpine:latest
--light deprecated (default: false) [$TRIVY_LIGHT]
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY] # Generate json result
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS] $ trivy image --format json --output result.json alpine:3.15
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
--cache-ttl value cache TTL when using redis as cache backend (default: 0s) [$TRIVY_CACHE_TTL] # Generate a report in the CycloneDX format
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] $ trivy image --format cyclonedx --output result.cdx alpine:3.15
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE]
--db-repository value OCI repository to retrieve trivy-db from (default: "ghcr.io/aquasecurity/trivy-db") [$TRIVY_DB_REPOSITORY] Scan Flags
--skip-files value specify the file paths to skip traversal (accepts multiple inputs) [$TRIVY_SKIP_FILES] --offline-scan do not issue API requests to identify dependencies
--skip-dirs value specify the directories where the traversal is skipped (accepts multiple inputs) [$TRIVY_SKIP_DIRS] --security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--server value server address [$TRIVY_SERVER] --skip-dirs string specify the directories where the traversal is skipped
--token value for authentication in client/server mode [$TRIVY_TOKEN] --skip-files string specify the file paths to skip traversal
--token-header value specify a header name for token in client/server mode (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER]
--custom-headers value custom headers in client/server mode (accepts multiple inputs) [$TRIVY_CUSTOM_HEADERS] Report Flags
--help, -h show help (default: false) --dependency-tree show dependency origin tree (EXPERIMENTAL)
--exit-code int specify exit code when any security issues are found
-f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
-o, --output string output file name
-s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
-t, --template string output template
Cache Flags
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Image Flags
--input string input file path instead of image name
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine)
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Secret Flags
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
Client/Server Flags
--custom-headers strings custom headers in client mode
--server string server address in client mode
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,32 +1,49 @@
Trivy has several sub commands, image, fs, repo, client and server. Trivy has several sub commands, image, fs, repo, client and server.
``` bash ``` bash
NAME: Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets
trivy - Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets
USAGE: Usage:
trivy [global options] command [command options] target trivy [command]
VERSION: Examples:
dev # Scan a container image
$ trivy image python:3.4-alpine
COMMANDS: # Scan a container image from a tar archive
image, i scan an image $ trivy image --input ruby-3.1.tar
filesystem, fs scan local filesystem for language-specific dependencies and config files
rootfs scan rootfs
repository, repo scan remote repository
server, s server mode
config, conf scan config files
plugin, p manage plugins
kubernetes, k8s scan kubernetes vulnerabilities and misconfigurations
sbom generate SBOM for an artifact
version print the version
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS: # Scan local filesystem
--quiet, -q suppress progress bar and log output (default: false) [$TRIVY_QUIET] $ trivy fs .
--debug, -d debug mode (default: false) [$TRIVY_DEBUG]
--cache-dir value cache directory (default: "/Users/teppei/Library/Caches/trivy") [$TRIVY_CACHE_DIR] # Run in server mode
--help, -h show help (default: false) $ trivy server
--version, -v print the version (default: false)
Available Commands:
config Scan config files for misconfigurations
filesystem Scan local filesystem
help Help about any command
image Scan a container image
kubectl scan kubectl resources
kubernetes scan kubernetes cluster
module Manage modules
plugin Manage plugins
repository Scan a remote repository
rootfs Scan rootfs
sbom Scan SBOM for vulnerabilities
server Server mode
version Print the version
Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
-f, --format string version format (json)
-h, --help help for trivy
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
Use "trivy [command] --help" for more information about a command.
``` ```

View File

@@ -1,17 +1,27 @@
# Module # Module
```bash ```bash
NAME: Manage modules
trivy module - manage modules
USAGE: Usage:
trivy module command [command options] [arguments...] trivy module [command]
COMMANDS: Aliases:
install, i install a module module, m
uninstall, u uninstall a module
help, h Shows a list of commands or help for one command
OPTIONS: Available Commands:
--help, -h show help (default: false) install Install a module
uninstall Uninstall a module
Flags:
-h, --help help for module
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,21 +1,31 @@
# Plugin # Plugin
```bash ```bash
NAME: Manage plugins
trivy plugin - manage plugins
USAGE: Usage:
trivy plugin command [command options] plugin_uri trivy plugin [command]
COMMANDS: Aliases:
install, i install a plugin plugin, p
uninstall, u uninstall a plugin
list, l list installed plugin
info information about a plugin
run, r run a plugin on the fly
update update an existing plugin
help, h Shows a list of commands or help for one command
OPTIONS: Available Commands:
--help, -h show help (default: false) Uninstall uninstall a plugin
info Show information about the specified plugin
install Install a plugin
list List installed plugin
run Run a plugin on the fly
update Update an existing plugin
Flags:
-h, --help help for plugin
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,38 +1,82 @@
# Repository # Repository
```bash ```bash
NAME: Scan a remote repository
trivy repository - scan remote repository
USAGE: Usage:
trivy repository [command options] repo_url trivy repository [flags] REPO_URL
OPTIONS: Aliases:
--template value, -t value output template [$TRIVY_TEMPLATE] repository, repo
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
--input value, -i value input file path instead of image name [$TRIVY_INPUT] Examples:
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] # Scan your remote git repository
--output value, -o value output file name [$TRIVY_OUTPUT] $ trivy repo https://github.com/knqyf263/trivy-ci-test
--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] Scan Flags
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE] --offline-scan do not issue API requests to identify dependencies
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE] --security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED] --skip-dirs string specify the directories where the traversal is skipped
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS] --skip-files string specify the file paths to skip traversal
--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] Report Flags
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] --dependency-tree show dependency origin tree (EXPERIMENTAL)
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND] --exit-code int specify exit code when any security issues are found
--cache-ttl value cache TTL when using redis as cache backend (default: 0s) [$TRIVY_CACHE_TTL] -f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT] --ignore-policy string specify the Rego file path to evaluate each vulnerability
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS] --ignorefile string specify .trivyignore file (default ".trivyignore")
--quiet, -q suppress progress bar and log output (default: false) [$TRIVY_QUIET] --list-all-pkgs enabling the option will output all packages regardless of vulnerability
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY] -o, --output string output file name
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS] -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] -t, --template string output template
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE]
--db-repository value OCI repository to retrieve trivy-db from (default: "ghcr.io/aquasecurity/trivy-db") [$TRIVY_DB_REPOSITORY] Cache Flags
--skip-files value specify the file paths to skip traversal (accepts multiple inputs) [$TRIVY_SKIP_FILES] --cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--skip-dirs value specify the directories where the traversal is skipped (accepts multiple inputs) [$TRIVY_SKIP_DIRS] --cache-ttl duration cache TTL when using redis as cache backend
--help, -h show help (default: false) --clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Secret Flags
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
Client/Server Flags
--custom-headers strings custom headers in client mode
--server string server address in client mode
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Repository Flags
--branch string pass the branch name to be scanned
--commit string pass the commit hash to be scanned
--tag string pass the tag name to be scanned
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,36 +1,74 @@
# Rootfs # Rootfs
```bash ```bash
NAME: Scan rootfs
trivy rootfs - scan rootfs
USAGE: Usage:
trivy rootfs [command options] dir trivy rootfs [flags] ROOTDIR
OPTIONS: Examples:
--template value, -t value output template [$TRIVY_TEMPLATE] # Scan unpacked filesystem
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT] $ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] $ trivy rootfs /tmp/rootfs
--output value, -o value output file name [$TRIVY_OUTPUT]
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE] # Scan from inside a container
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE] $ docker run --rm -it alpine:3.11
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE] / # curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE] / # trivy rootfs /
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED] Scan Flags
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE] --offline-scan do not issue API requests to identify dependencies
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS] --security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE] --skip-dirs string specify the directories where the traversal is skipped
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND] --skip-files string specify the file paths to skip traversal
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS] Report Flags
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY] --dependency-tree show dependency origin tree (EXPERIMENTAL)
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS] --exit-code int specify exit code when any security issues are found
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] -f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES] --ignore-policy string specify the Rego file path to evaluate each vulnerability
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS] --ignorefile string specify .trivyignore file (default ".trivyignore")
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY] --list-all-pkgs enabling the option will output all packages regardless of vulnerability
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA] -o, --output string output file name
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES] -s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
--help, -h show help (default: false) -t, --template string output template
Cache Flags
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Misconfiguration Flags
--config-data strings specify paths from which data for the Rego policies will be recursively loaded
--config-policy strings specify paths to the Rego policy files directory, applying config files
--file-patterns strings specify config file patterns, available with '--security-checks config'
--include-non-failures include successes and exceptions, available with '--security-checks config'
--policy-namespaces strings Rego namespaces
--trace enable more verbose trace output for custom queries
Secret Flags
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -1,27 +1,67 @@
# SBOM # SBOM
```bash ```bash
NAME: Scan SBOM for vulnerabilities
trivy sbom - generate SBOM for an artifact
USAGE: Usage:
trivy sbom [command options] ARTIFACT trivy sbom [flags] SBOM_PATH
DESCRIPTION: Examples:
ARTIFACT can be a container image, file path/directory, git repository or container image archive. See examples. # Scan CycloneDX and show the result in tables
$ trivy sbom /path/to/report.cdx
OPTIONS: # Scan CycloneDX and generate a CycloneDX report
--output value, -o value output file name [$TRIVY_OUTPUT] $ trivy sbom --format cyclonedx /path/to/report.cdx
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT] Scan Flags
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY] --offline-scan do not issue API requests to identify dependencies
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN] --security-checks string comma-separated list of what security issues to detect (vuln,config,secret) (default "vuln,secret")
--db-repository value OCI repository to retrieve trivy-db from (default: "ghcr.io/aquasecurity/trivy-db") [$TRIVY_DB_REPOSITORY] --skip-dirs string specify the directories where the traversal is skipped
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE] --skip-files string specify the file paths to skip traversal
--skip-files value specify the file paths to skip traversal (accepts multiple inputs) [$TRIVY_SKIP_FILES]
--skip-dirs value specify the directories where the traversal is skipped (accepts multiple inputs) [$TRIVY_SKIP_DIRS] Report Flags
--artifact-type value, --type value input artifact type (image, fs, repo, archive) (default: "image") [$TRIVY_ARTIFACT_TYPE] --dependency-tree show dependency origin tree (EXPERIMENTAL)
--sbom-format value, --format value SBOM format (cyclonedx, spdx, spdx-json) (default: "cyclonedx") [$TRIVY_SBOM_FORMAT] --exit-code int specify exit code when any security issues are found
--help, -h show help (default: false) -f, --format string format (table, json, sarif, template, cyclonedx, spdx, spdx-json, github) (default "table")
``` --ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--list-all-pkgs enabling the option will output all packages regardless of vulnerability
-o, --output string output file name
-s, --severity string severities of security issues to be displayed (comma separated) (default "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
-t, --template string output template
Cache Flags
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Vulnerability Flags
--ignore-unfixed display only fixed vulnerabilities
--vuln-type string comma-separated list of vulnerability types (os,library) (default "os,library")
Client/Server Flags
--custom-headers strings custom headers in client mode
--server string server address in client mode
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
```

View File

@@ -1,22 +1,48 @@
# Server # Server
```bash ```bash
NAME: Server mode
trivy server - server mode
USAGE: Usage:
trivy server [command options] [arguments...] trivy server [flags]
OPTIONS: Aliases:
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE] server, s
--download-db-only download/update vulnerability database but don't run a scan (default: false) [$TRIVY_DOWNLOAD_DB_ONLY]
--insecure allow insecure server connections when using SSL (default: false) [$TRIVY_INSECURE] Examples:
--reset remove all caches and database (default: false) [$TRIVY_RESET] # Run a server
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND] $ trivy server
--cache-ttl value cache TTL when using redis as cache backend (default: 0s) [$TRIVY_CACHE_TTL]
--db-repository value OCI repository to retrieve trivy-db from (default: "ghcr.io/aquasecurity/trivy-db") [$TRIVY_DB_REPOSITORY] # Listen on 0.0.0.0:10000
--token value for authentication in client/server mode [$TRIVY_TOKEN] $ trivy server --listen 0.0.0.0:10000
--token-header value specify a header name for token in client/server mode (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER]
--listen value listen address (default: "localhost:4954") [$TRIVY_LISTEN]
--help, -h show help (default: false) Cache Flags
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
--cache-ttl duration cache TTL when using redis as cache backend
--clear-cache clear image caches without scanning
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
--redis-key string redis key file location, if using redis as cache backend
DB Flags
--db-repository string OCI repository to retrieve trivy-db from" (default "ghcr.io/aquasecurity/trivy-db")
--download-db-only download/update vulnerability database but don't run a scan
--no-progress suppress progress bar
--reset remove all caches and database
--skip-db-update skip updating vulnerability database
Client/Server Flags
--listen string listen address in server mode (default "localhost:4954")
--token string for authentication in client/server mode
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
Global Flags:
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
-c, --config string config path (default "trivy.yaml")
-d, --debug debug mode
--insecure allow insecure server connections when using TLS
-q, --quiet suppress progress bar and log output
--timeout duration timeout (default 5m0s)
-v, --version show version
``` ```

View File

@@ -0,0 +1,289 @@
# Config file
Trivy can be customized by tweaking a `trivy.yaml` file. The config path can be overridden by the `--config` flag.
An example is [here][example].
## Global Options
```
# Same as '--quiet'
# Default is false
quiet: false
# Same as '--debug'
# Default is false
debug: false
# Same as '--insecure'
# Default is false
insecure: false
# Same as '--timeout'
# Default is '5m'
timeout: 10m
# Same as '--cache-dir'
# Default is your system cache dir
cache-dir: $HOME/.cache/trivy
```
## Report Options
```
# Same as '--format'
# Default is 'table'
format: table
# Same as '--report' (available with 'trivy k8s')
# Default is all
report: all
# Same as '--template'
# Default is empty
template:
# Same as '--dependency-tree'
# Default is false
dependency-tree: false
# Same as '--list-all-pkgs'
# Default is false
list-all-pkgs: false
# Same as '--ignorefile'
# Default is '.trivyignore'
ignorefile: .trivyignore
# Same as '--ignore-policy'
# Default is empty
ignore-policy:
# Same as '--exit-code'
# Default is 0
exit-code: 0
# Same as '--output'
# Default is empty (stdout)
output:
# Same as '--severity'
# Default is all severities
severity:
- UNKNOWN
- LOW
- MEDIUM
- HIGH
- CRITICAL
```
## Scan Options
Available in client/server mode
```
scan:
# Same as '--skip-dirs'
# Default is empty
skip-dirs:
- usr/local/
- etc/
# Same as '--skip-files'
# Default is empty
skip-files:
- package-dev.json
# Same as '--offline-scan'
# Default is false
offline-scan: false
# Same as '--security-checks'
# Default depends on subcommand
security-checks:
- vuln
- config
- secret
```
## Cache Options
```
cache:
# Same as '--cache-backend'
# Default is 'fs'
backend: 'fs'
# Same as '--cache-ttl'
# Default is 0 (no ttl)
ttl: 0
# Redis options
redis:
# Same as '--redis-ca'
# Default is empty
ca:
# Same as '--redis-cert'
# Default is empty
cert:
# Same as '--redis-key'
# Default is empty
key:
```
## DB Options
```
db:
# Same as '--skip-db-update'
# Default is false
skip-update: false
# Same as '--no-progress'
# Default is false
no-progress: false
# Same as '--db-repository'
# Default is 'github.com/aquasecurity-trivy-repo'
repository: github.com/aquasecurity-trivy-repo
```
## Image Options
Available with container image scanning
```
image:
# Same as '--input' (available with 'trivy image')
# Default is empty
input:
# Same as '--removed-pkgs'
# Default is false
removed-pkgs: false
```
## Vulnerability Options
Available with vulnerability scanning
```
vulnerability:
# Same as '--vuln-type'
# Default is 'os,library'
type:
- os
- library
# Same as '--ignore-unfixed'
# Default is false
ignore-unfixed: false
```
## Secret Options
Available with secret scanning
```
secret:
# Same as '--secret-config'
# Default is 'trivy-secret.yaml'
config: config/trivy/secret.yaml
```
## Misconfiguration Options
Available with misconfiguration scanning
```
misconfiguration:
# Same as '--file-patterns'
# Default is empty
file-patterns:
-
# Same as '--include-non-failures'
# Default is false
include-non-failures: false
# Same as '--trace'
# Default is false
trace: false
# Same as '--config-policy'
# Default is empty
policy:
- policy/repository
- policy/custom
# Same as '--config-data'
# Default is empty
data:
- data/
# Same as '--policy-namespaces'
# Default is empty
namespaces:
- opa.examples
- users
```
## Kubernetes Options
Available with Kubernetes scanning
```
kubernetes:
# Same as '--context'
# Default is empty
context:
# Same as '--namespace'
# Default is empty
namespace:
```
## Repository Options
Available with git repository scanning (`trivy repo`)
```
repository:
# Same as '--branch'
# Default is empty
branch:
# Same as '--commit'
# Default is empty
commit:
# Same as '--tag'
# Default is empty
tag:
```
## Client/Server Options
Available in client/server mode
```
server:
# Same as '--server' (available in client mode)
# Default is empty
addr: http://localhost:4954
# Same as '--token'
# Default is empty
token: "something-secret"
# Same as '--token-header'
# Default is 'Trivy-Token'
token-header: 'My-Token-Header'
# Same as '--custom-headers'
# Default is empty
custom-headers:
- scanner: trivy
- x-api-token: xxx
# Same as '--listen' (available in server mode)
# Default is 'localhost:4954'
listen: 0.0.0.0:10000
```
[example]: https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/examples/trivy-conf/trivy.yaml

View File

@@ -0,0 +1,17 @@
# Environment variables
Trivy can be customized by environment variables.
The environment variable key is the flag name converted by the following procedure.
- Add `TRIVY_` prefix
- Make it all uppercase
- Replace `-` with `_`
For example,
- `--debug` => `TRIVY_DEBUG`
- `--cache-dir` => `TRIVY_CACHE_DIR`
```
$ TRIVY_DEBUG=true TRIVY_SEVERITY=CRITICAL trivy image alpine:3.15
```

View File

@@ -106,7 +106,19 @@ If trivy is running behind corporate firewall, you have to add the following url
!!! error !!! error
--skip-update cannot be specified with the old DB schema. --skip-update cannot be specified with the old DB schema.
Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow [the instruction of air-gapped environment][../advanced/air-gap.md]. Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow [the instruction of air-gapped environment][air-gapped].
### Multiple Trivy servers
!!! error
```
$ trivy image --server http://xxx.com:xxxx test-image
...
- twirp error internal: failed scan, test-image: failed to apply layers: layer cache missing: sha256:*****
```
To run multiple Trivy servers, you need to use Redis as the cache backend so that those servers can share the cache.
Follow [this instruction][redis-cache] to do so.
## Homebrew ## Homebrew
### Scope error ### Scope error
@@ -157,4 +169,5 @@ Try again with `--reset` option:
$ trivy image --reset $ trivy image --reset
``` ```
[air-gapped]: ../how-to-guides/air-gap.md [air-gapped]: ../advanced/air-gap.md
[redis-cache]: ../../vulnerability/examples/cache/#cache-backend

View File

@@ -1,5 +1,6 @@
# CycloneDX # CycloneDX
## Reporting
Trivy generates JSON reports in the [CycloneDX][cyclonedx] format. Trivy generates JSON reports in the [CycloneDX][cyclonedx] format.
Note that XML format is not supported at the moment. Note that XML format is not supported at the moment.
@@ -230,4 +231,32 @@ $ cat result.json | jq .
</details> </details>
## Scanning
Trivy can take CycloneDX as an input and scan for vulnerabilities.
To scan SBOM, you can use the `sbom` subcommand and pass the path to your CycloneDX report.
```bash
$ trivy sbom /path/to/cyclonedx.json
cyclonedx.json (alpine 3.7.1)
=========================
Total: 3 (CRITICAL: 3)
┌─────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version │ Fixed Version │ Title │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ curl │ CVE-2018-14618 │ CRITICAL │ 7.61.0-r0 │ 7.61.1-r0 │ curl: NTLM password overflow via integer overflow │
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-14618 │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ libbz2 │ CVE-2019-12900 │ CRITICAL │ 1.0.6-r6 │ 1.0.6-r7 │ bzip2: out-of-bounds write in function BZ2_decompress │
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-12900 │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ sqlite-libs │ CVE-2019-8457 │ CRITICAL │ 3.21.0-r1 │ 3.25.3-r1 │ sqlite: heap out-of-bound read in function rtreenode()
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-8457 │
└─────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────────┘
```
!!! note
If you want to generate a CycloneDX report from a CycloneDX input, please be aware that the output stores references to your original CycloneDX report and contains only detected vulnerabilities, not components.
[cyclonedx]: https://cyclonedx.org/ [cyclonedx]: https://cyclonedx.org/

View File

@@ -1,6 +1,7 @@
# SBOM # SBOM
Trivy currently supports the following SBOM formats. ## Reporting
Trivy can generate the following SBOM formats.
- [CycloneDX][cyclonedx] - [CycloneDX][cyclonedx]
- [SPDX][spdx] - [SPDX][spdx]
@@ -11,10 +12,8 @@ To generate SBOM, you can use the `--format` option for each subcommand such as
$ trivy image --format cyclonedx --output result.json alpine:3.15 $ trivy image --format cyclonedx --output result.json alpine:3.15
``` ```
In addition, you can use the `trivy sbom` subcommand.
``` ```
$ trivy sbom alpine:3.15 $ trivy fs --format cyclonedx --output result.json /app/myproject
``` ```
<details> <details>
@@ -177,18 +176,37 @@ $ trivy sbom alpine:3.15
</details> </details>
`fs`, `repo` and `archive` also work with `sbom` subcommand. ## Scanning
Trivy also can take the following SBOM formats as an input and scan for vulnerabilities.
- CycloneDX
To scan SBOM, you can use the `sbom` subcommand and pass the path to the SBOM.
```bash
$ trivy sbom /path/to/cyclonedx.json
cyclonedx.json (alpine 3.7.1)
=========================
Total: 3 (CRITICAL: 3)
┌─────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version │ Fixed Version │ Title │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ curl │ CVE-2018-14618 │ CRITICAL │ 7.61.0-r0 │ 7.61.1-r0 │ curl: NTLM password overflow via integer overflow │
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-14618 │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ libbz2 │ CVE-2019-12900 │ CRITICAL │ 1.0.6-r6 │ 1.0.6-r7 │ bzip2: out-of-bounds write in function BZ2_decompress │
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-12900 │
├─────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ sqlite-libs │ CVE-2019-8457 │ CRITICAL │ 3.21.0-r1 │ 3.25.3-r1 │ sqlite: heap out-of-bound read in function rtreenode()
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-8457 │
└─────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────────┘
``` ```
# filesystem
$ trivy sbom --artifact-type fs /path/to/project
# repository
$ trivy sbom --artifact-type repo github.com/aquasecurity/trivy-ci-test
# container image archive !!! note
$ trivy sbom --artifact-type archive alpine.tar CycloneDX XML and SPDX are not supported at the moment.
```
[cyclonedx]: cyclonedx.md [cyclonedx]: cyclonedx.md
[spdx]: spdx.md [spdx]: spdx.md

View File

@@ -1,22 +1,21 @@
# OS # OS
| OS | Source | | OS | Source |
| ---------------| ---------------------------------------- | |--------------------|---------------------------------------------|
| Arch Linux | [Vulnerable Issues][arch] | | Arch Linux | [Vulnerable Issues][arch] |
| Alpine Linux | [secdb][alpine] | | Alpine Linux | [secdb][alpine] |
| Amazon Linux 1 | [Amazon Linux Security Center][amazon1] | | Amazon Linux | [Amazon Linux Security Center][amazon] |
| Amazon Linux 2 | [Amazon Linux Security Center][amazon2] | | Debian | [Security Bug Tracker][debian-tracker] |
| Debian | [Security Bug Tracker][debian-tracker] | | | [OVAL][debian-oval] |
| | [OVAL][debian-oval] | | Ubuntu | [Ubuntu CVE Tracker][ubuntu] |
| Ubuntu | [Ubuntu CVE Tracker][ubuntu] | | RHEL/CentOS | [OVAL][rhel-oval] |
| RHEL/CentOS | [OVAL][rhel-oval] | | | [Security Data][rhel-api] |
| | [Security Data][rhel-api] | | AlmaLinux | [AlmaLinux Product Errata][alma] |
| AlmaLinux | [AlmaLinux Product Errata][alma] | | Rocky Linux | [Rocky Linux UpdateInfo][rocky] |
| Rocky Linux | [Rocky Linux UpdateInfo][rocky] | | Oracle Linux | [OVAL][oracle] |
| Oracle Linux | [OVAL][oracle] | | CBL-Mariner | [OVAL][mariner] |
| CBL-Mariner | [OVAL][mariner] | | OpenSUSE/SLES | [CVRF][suse] |
| OpenSUSE/SLES | [CVRF][suse] | | Photon OS | [Photon Security Advisory][photon] |
| Photon OS | [Photon Security Advisory][photon] |
# Programming Language # Programming Language
@@ -57,8 +56,7 @@ The severity is from the selected data source. If the data source does not provi
[arch]: https://security.archlinux.org/ [arch]: https://security.archlinux.org/
[alpine]: https://secdb.alpinelinux.org/ [alpine]: https://secdb.alpinelinux.org/
[amazon1]: https://alas.aws.amazon.com/ [amazon]: https://alas.aws.amazon.com/
[amazon2]: https://alas.aws.amazon.com/alas2.html
[debian-tracker]: https://security-tracker.debian.org/tracker/ [debian-tracker]: https://security-tracker.debian.org/tracker/
[debian-oval]: https://www.debian.org/security/oval/ [debian-oval]: https://www.debian.org/security/oval/
[ubuntu]: https://ubuntu.com/security/cve [ubuntu]: https://ubuntu.com/security/cve

View File

@@ -2,26 +2,28 @@
`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[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] |Dev dependencies | | Language | File | Image[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] | 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 | | | pnpm-lock.yaml | - | - | | | excluded |
| .NET | packages.lock.json | | | | | included | | | package.json | | | - | - | excluded |
| | packages.config | ✅ | | ✅ | ✅ | excluded | | .NET | packages.lock.json | ✅ | | ✅ | ✅ | included |
| Java | JAR/WAR/PAR/EAR[^3][^4] | | | - | - | included | | | packages.config | | | | | excluded |
| | pom.xml[^5] | - | - | ✅ | ✅ | excluded | | | .deps.json | | | ✅ | ✅ | excluded |
| Go | Binaries built by Go[^6] | | | - | - | excluded | | Java | JAR/WAR/PAR/EAR[^3][^4] | | | - | - | included |
| | go.mod[^7] | - | - | ✅ | ✅ | included | | | pom.xml[^5] | - | - | ✅ | ✅ | excluded |
| Rust | Cargo.lock | | | | | included | | Go | Binaries built by Go[^6] | | ✅ | - | - | excluded |
| | go.mod[^7] | - | - | ✅ | ✅ | included |
| Rust | Cargo.lock | ✅ | ✅ | ✅ | ✅ | included |
The path of these files does not matter. The path of these files does not matter.

View File

@@ -12,7 +12,7 @@ The unfixed/unfixable vulnerabilities mean that the patch has not yet been provi
| Rocky Linux | 8 | Installed by yum/rpm | NO | | Rocky Linux | 8 | Installed by yum/rpm | NO |
| Oracle Linux | 5, 6, 7, 8 | Installed by yum/rpm | NO | | Oracle Linux | 5, 6, 7, 8 | Installed by yum/rpm | NO |
| CBL-Mariner | 1.0, 2.0 | Installed by yum/rpm | YES | | CBL-Mariner | 1.0, 2.0 | Installed by yum/rpm | YES |
| Amazon Linux | 1, 2 | Installed by yum/rpm | NO | | Amazon Linux | 1, 2, 2022 | Installed by yum/rpm | NO |
| openSUSE Leap | 42, 15 | Installed by zypper/rpm | NO | | openSUSE Leap | 42, 15 | Installed by zypper/rpm | NO |
| SUSE Enterprise Linux | 11, 12, 15 | Installed by zypper/rpm | NO | | SUSE Enterprise Linux | 11, 12, 15 | Installed by zypper/rpm | NO |
| Photon OS | 1.0, 2.0, 3.0, 4.0 | Installed by tdnf/yum/rpm | NO | | Photon OS | 1.0, 2.0, 3.0, 4.0 | Installed by tdnf/yum/rpm | NO |

View File

@@ -6,7 +6,7 @@ The following table provides an outline of the features Trivy offers.
| Version | Container image | Virtual machine | Distroless | Multi-arch | Unfixed support | | Version | Container image | Virtual machine | Distroless | Multi-arch | Unfixed support |
|---------|:---------------:|:---------------:|:----------:|:------------:|:---------------:| |---------|:---------------:|:---------------:|:----------:|:------------:|:---------------:|
| 1.0 | ✔ | ✔ | | amd64, arm64 | ✔ | | 1.0 | ✔ | ✔ | | amd64, arm64 | ✔ |
| 2.0 | ✔ | ✔ | ✔ | amd64, arm64 | ✔ | | 2.0 | ✔ | ✔ | ✔ | amd64, arm64 | ✔ |
### Examples ### Examples

View File

@@ -15,7 +15,7 @@ Modern software development relies on the use of third-party libraries.
Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph. Third-party dependencies also depend on others so a list of dependencies can be represented as a dependency graph.
In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree. In some cases, vulnerable dependencies are not linked directly, and it requires analyses of the tree.
To make this task simpler Trivy can show a dependency origin tree with the `--dependency-tree` flag. To make this task simpler Trivy can show a dependency origin tree with the `--dependency-tree` flag.
This flag is available with the `--format table` flag only. This flag is only available with the `fs` or `repo` commands and the `--format table` flag.
This tree is the reverse of the npm list command. This tree is the reverse of the npm list command.
However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update. However, if you want to resolve a vulnerability in a particular indirect dependency, the reversed tree is useful to know where that dependency comes from and identify which package you actually need to update.
@@ -63,33 +63,6 @@ Then, you can try to update **axios@0.21.4** and **cra-append-sw@2.7.0** to reso
!!! note !!! note
Only Node.js (package-lock.json) is supported at the moment. Only Node.js (package-lock.json) is supported at the moment.
## JSON
Similar structure is included in JSON output format
```json
"VulnerabilityID": "CVE-2022-0235",
"PkgID": "node-fetch@1.7.3",
"PkgName": "node-fetch",
"PkgParents": [
{
"ID": "isomorphic-fetch@2.2.1",
"Parents": [
{
"ID": "fbjs@0.8.18",
"Parents": [
{
"ID": "styled-components@3.1.3"
}
]
}
]
}
],
```
!!! caution
As of May 2022 the feature is supported for `npm` dependency parser only
## JSON ## JSON
``` ```

View File

@@ -147,6 +147,30 @@ Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5)
</details> </details>
## Scanning a Branch
Pass a `--branch` agrument with a valid branch name on the remote repository provided:
```
$ trivy repo --branch <branch-name> <repo-name>
```
## Scanning upto a Commit
Pass a `--commit` agrument with a valid commit hash on the remote repository provided:
```
$ trivy repo --commit <commit-hash> <repo-name>
```
## Scanning a Tag
Pass a `--tag` agrument with a valid tag on the remote repository provided:
```
$ trivy repo --tag <tag-name> <repo-name>
```
## Scanning Private Repositories ## Scanning Private Repositories
In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned. In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned.

View File

@@ -4,7 +4,7 @@ Trivy detects three types of security issues:
- [Vulnerabilities][vuln] - [Vulnerabilities][vuln]
- [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless) - [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
- [Language-specific packages][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go) - [Language-specific packages][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, pnpm, Cargo, NuGet, Maven, and Go)
- [Misconfigurations][misconf] - [Misconfigurations][misconf]
- Kubernetes - Kubernetes
- Docker - Docker

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 397 KiB

View File

@@ -23,12 +23,16 @@ All you need to do for scanning is to specify a target such as an image name of
</div> </div>
<figure style="text-align: center"> <figure style="text-align: center">
<img src="imgs/vuln-demo.gif" width="1000"> <video width="1000" autoplay muted controls loop>
<source src="https://user-images.githubusercontent.com/1161307/171013513-95f18734-233d-45d3-aaf5-d6aec687db0e.mov" type="video/mp4" />
</video>
<figcaption>Demo: Vulnerability Detection</figcaption> <figcaption>Demo: Vulnerability Detection</figcaption>
</figure> </figure>
<figure style="text-align: center"> <figure style="text-align: center">
<img src="imgs/misconf-demo.gif" width="1000"> <video width="1000" autoplay muted controls loop>
<source src="https://user-images.githubusercontent.com/1161307/171013917-b1f37810-f434-465c-b01a-22de036bd9b3.mov" type="video/mp4" />
</video>
<figcaption>Demo: Misconfiguration Detection</figcaption> <figcaption>Demo: Misconfiguration Detection</figcaption>
</figure> </figure>

View File

@@ -11,7 +11,7 @@ __rego_metadata__ := {
__rego_input__ := {"selector": [{"type": "dockerfile"}]} __rego_input__ := {"selector": [{"type": "dockerfile"}]}
deny[res] { deny[res] {
add := input.stages[_][_] add := input.Stages[_].Commands[_]
add.Cmd == "add" add.Cmd == "add"
startswith(add.Value[0], "http://") startswith(add.Value[0], "http://")

View File

@@ -1,21 +1,21 @@
package user.dockerfile.ID002 package user.dockerfile.ID002
test_http_denied { test_http_denied {
r := deny with input as {"stages": {"alpine:3.13": [ r := deny with input as {"Stages": [{"Name": "alpine:3.31", "Commands": [
{"Cmd": "from", "Value": ["alpine:3.13"]}, {"Cmd": "from", "Value": ["alpine:3.13"]},
{"Cmd": "add", "Value": ["http://example.com/big.tar.xz", "/usr/src/things/"]}, {"Cmd": "add", "Value": ["http://example.com/big.tar.xz", "/usr/src/things/"]},
{"Cmd": "run", "Value": ["tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things"]}, {"Cmd": "run", "Value": ["tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things"]},
]}} ]}]}
count(r) == 1 count(r) == 1
r[_] == "HTTP not allowed: 'http://example.com/big.tar.xz'" r[_] == "HTTP not allowed: 'http://example.com/big.tar.xz'"
} }
test_http_allowed { test_http_allowed {
r := deny with input as {"stages": {"alpine:3.13": [ r := deny with input as {"Stages": [{"Name": "alpine:3.31", "Commands": [
{"Cmd": "from", "Value": ["alpine:3.13"]}, {"Cmd": "from", "Value": ["alpine:3.13"]},
{"Cmd": "add", "Value": ["https://example.com/big.tar.xz", "/usr/src/things/"]}, {"Cmd": "add", "Value": ["https://example.com/big.tar.xz", "/usr/src/things/"]},
]}} ]}]}
count(r) == 0 count(r) == 0
} }

View File

@@ -0,0 +1,24 @@
timeout: 10m
format: json
dependency-tree: true
list-all-pkgs: true
exit-code: 1
output: result.json
severity:
- HIGH
- CRITICAL
scan:
skip-dirs:
- /lib64
- /lib
- /usr/lib
- /usr/include
security-checks:
- vuln
- secret
vulnerability:
type:
- os
- library
ignore-unfixed: true

207
go.mod
View File

@@ -6,66 +6,72 @@ require (
github.com/CycloneDX/cyclonedx-go v0.6.0 github.com/CycloneDX/cyclonedx-go v0.6.0
github.com/Masterminds/sprig/v3 v3.2.2 github.com/Masterminds/sprig/v3 v3.2.2
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/alicebob/miniredis/v2 v2.21.0 github.com/alicebob/miniredis/v2 v2.22.0
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/go-dep-parser v0.0.0-20220607141748-ab2deea55bdf github.com/aquasecurity/go-dep-parser v0.0.0-20220626060741-179d0b167e5f
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
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492
github.com/aquasecurity/table v1.5.1 github.com/aquasecurity/table v1.6.0
github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516 github.com/aquasecurity/testdocker v0.0.0-20210911155206-e1e85f5a1516
github.com/aquasecurity/trivy-db v0.0.0-20220602091213-39d8a6798e07 github.com/aquasecurity/trivy-db v0.0.0-20220627104749-930461748b63
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20220613131930-79b2cb425b18 github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20220719205641-79488fbb4710
github.com/caarlos0/env/v6 v6.9.3 github.com/caarlos0/env/v6 v6.9.3
github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.8 github.com/cheggaaa/pb/v3 v3.0.8
github.com/docker/docker v20.10.16+incompatible github.com/containerd/containerd v1.6.6
github.com/docker/docker v20.10.17+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
github.com/go-enry/go-license-detector/v4 v4.3.0
github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis/v8 v8.11.5
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
github.com/google/go-containerregistry v0.7.1-0.20211214010025-a65b7844a475 github.com/google/go-containerregistry v0.7.1-0.20211214010025-a65b7844a475
github.com/google/licenseclassifier/v2 v2.0.0-pre5
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/google/wire v0.5.0 github.com/google/wire v0.5.0
github.com/hashicorp/go-getter v1.6.2 github.com/hashicorp/go-getter v1.6.2
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 github.com/knqyf263/go-rpm-version v0.0.0-20220614171824-631e686d1075
github.com/kylelemons/godebug v1.1.0 github.com/kylelemons/godebug v1.1.0
github.com/mailru/easyjson v0.7.6 github.com/liamg/memoryfs v1.4.2
github.com/liamg/tml v0.6.0
github.com/mailru/easyjson v0.7.7
github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08 github.com/masahiro331/go-mvn-version v0.0.0-20210429150710-d3157d602a08
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/open-policy-agent/opa v0.41.0 github.com/open-policy-agent/opa v0.42.0
github.com/owenrumney/go-sarif/v2 v2.1.1 github.com/owenrumney/go-sarif/v2 v2.1.2
github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a
github.com/samber/lo v1.21.0 github.com/samber/lo v1.24.0
github.com/sosedoff/gitkit v0.3.0 github.com/sosedoff/gitkit v0.3.0
github.com/stretchr/testify v1.7.2 github.com/spf13/cobra v1.5.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.8.0
github.com/testcontainers/testcontainers-go v0.13.0 github.com/testcontainers/testcontainers-go v0.13.0
github.com/tetratelabs/wazero v0.0.0-20220606011721-119b069ba23e github.com/tetratelabs/wazero v0.0.0-20220701105919-891761ac1ee2
github.com/twitchtv/twirp v8.1.2+incompatible github.com/twitchtv/twirp v8.1.2+incompatible
github.com/urfave/cli/v2 v2.8.1
github.com/xlab/treeprint v1.1.0 github.com/xlab/treeprint v1.1.0
go.etcd.io/bbolt v1.3.6
go.uber.org/zap v1.21.0 go.uber.org/zap v1.21.0
golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4 golang.org/x/exp v0.0.0-20220407100705-7b9b53b0aca4
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df
google.golang.org/protobuf v1.28.0 google.golang.org/protobuf v1.28.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
) )
require ( require github.com/emicklei/go-restful/v3 v3.8.0 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect
)
require ( require (
cloud.google.com/go v0.99.0 // indirect cloud.google.com/go v0.100.2 // indirect
cloud.google.com/go/compute v1.6.1 // indirect
cloud.google.com/go/iam v0.3.0 // indirect
cloud.google.com/go/storage v1.14.0 // indirect cloud.google.com/go/storage v1.14.0 // indirect
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible github.com/Azure/azure-sdk-for-go v66.0.0+incompatible
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.27 github.com/Azure/go-autorest/autorest v0.11.27
@@ -83,7 +89,7 @@ require (
github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/squirrel v1.5.2 // indirect github.com/Masterminds/squirrel v1.5.2 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.2 // indirect github.com/Microsoft/hcsshim v0.9.3 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect
@@ -93,50 +99,42 @@ require (
github.com/agext/levenshtein v1.2.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect
github.com/agnivade/levenshtein v1.0.1 // indirect github.com/agnivade/levenshtein v1.0.1 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect github.com/alecthomas/chroma v0.10.0 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/aquasecurity/defsec v0.68.3 github.com/aquasecurity/defsec v0.68.10
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
github.com/aws/aws-sdk-go v1.44.25 github.com/aws/aws-sdk-go v1.44.46
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/briandowns/spinner v1.12.0 // indirect github.com/briandowns/spinner v1.12.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/container-orchestrated-devices/container-device-interface v0.3.1 // indirect github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/cgroups v1.0.3 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/containerd/containerd v1.6.4
github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/fifo v1.0.0 // indirect github.com/containerd/fifo v1.0.0 // indirect
github.com/containerd/go-cni v1.1.6 // indirect
github.com/containerd/imgcrypt v1.1.5-0.20220421044638-8ba028dca028 // indirect
github.com/containerd/nerdctl v0.20.0
github.com/containerd/stargz-snapshotter v0.11.4 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.11.4 // indirect github.com/containerd/stargz-snapshotter/estargz v0.11.4 // indirect
github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 // indirect github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 // indirect
github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67 // indirect github.com/containerd/typeurl v1.0.2 // indirect
github.com/containernetworking/cni v1.1.1 // indirect
github.com/containers/ocicrypt v1.1.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-minhash v0.0.0-20170608043002-7fe510aff544 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/docker/cli v20.10.16+incompatible // indirect github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.4 // indirect github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect github.com/ekzhu/minhash-lsh v0.0.0-20171225071031-5c06ee8586a1 // indirect
github.com/emirpasic/gods v1.12.0 // indirect github.com/emirpasic/gods v1.12.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/ghodss/yaml v1.0.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect github.com/go-errors/errors v1.0.1 // indirect
github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/gcfg v1.5.0 // indirect
@@ -149,6 +147,8 @@ require (
github.com/go-openapi/swag v0.19.14 // indirect github.com/go-openapi/swag v0.19.14 // indirect
github.com/gobwas/glob v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-yaml v1.8.2 // indirect github.com/goccy/go-yaml v1.8.2 // indirect
github.com/gofrs/uuid v4.0.0+incompatible // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@@ -157,7 +157,7 @@ require (
github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-cmp v0.5.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/mux v1.8.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
@@ -168,74 +168,65 @@ require (
github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.4.0 // indirect github.com/hashicorp/go-version v1.4.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.12.0 // indirect github.com/hashicorp/hcl/v2 v2.12.0 // indirect
github.com/hhatto/gorst v0.0.0-20181029133204-ca9f730cac5b // indirect
github.com/huandu/xstrings v1.3.2 // indirect github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/ipfs/go-cid v0.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jdkato/prose v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.4 // indirect github.com/jmoiron/sqlx v1.3.4 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/compress v1.15.6 // indirect
github.com/klauspost/cpuid/v2 v2.0.6 // indirect
github.com/knqyf263/go-rpmdb v0.0.0-20220607073645-842f01763e21 github.com/knqyf263/go-rpmdb v0.0.0-20220607073645-842f01763e21
github.com/knqyf263/nested v0.0.1 github.com/knqyf263/nested v0.0.1
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/liamg/iamgo v0.0.6 // indirect github.com/liamg/iamgo v0.0.9 // indirect
github.com/liamg/jfather v0.0.7 // indirect github.com/liamg/jfather v0.0.7 // indirect
github.com/liamg/memoryfs v1.4.2
github.com/liamg/tml v0.6.0
github.com/lib/pq v1.10.4 // indirect github.com/lib/pq v1.10.4 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.5 // indirect github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/buildkit v0.10.3 github.com/moby/buildkit v0.10.3
github.com/moby/locker v1.0.1 // indirect github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mount v0.3.2 // indirect github.com/moby/sys/mount v0.3.3 // indirect
github.com/moby/sys/mountinfo v0.6.1 // indirect github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/sys/signal v0.7.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb // indirect
github.com/morikuni/aec v1.0.0 // indirect github.com/morikuni/aec v1.0.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.0.3 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multihash v0.0.15 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1 github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1
github.com/opencontainers/runc v1.1.2 // indirect github.com/opencontainers/runc v1.1.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220311020903-6969a0a09ab1 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20220311020903-6969a0a09ab1 // indirect
github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e // indirect
github.com/opencontainers/selinux v1.10.1 // indirect github.com/opencontainers/selinux v1.10.1 // indirect
github.com/owenrumney/squealer v1.0.1-0.20220510063705-c0be93f0edea // indirect github.com/owenrumney/squealer v1.0.1-0.20220510063705-c0be93f0edea // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_golang v1.12.2 // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/procfs v0.7.3 // indirect
@@ -247,53 +238,65 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e
github.com/sergi/go-diff v1.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect
github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b // indirect
github.com/shopspring/decimal v1.2.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spdx/tools-golang v0.3.0 github.com/spdx/tools-golang v0.3.0
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cobra v1.4.0 // indirect github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect github.com/stretchr/objx v0.4.0 // indirect
github.com/stretchr/objx v0.3.0 // indirect github.com/subosito/gotenv v1.4.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tidwall/gjson v1.14.1 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/ulikunitz/xz v0.5.8 // indirect github.com/ulikunitz/xz v0.5.8 // indirect
github.com/urfave/cli v1.22.9 // indirect
github.com/vbatts/tar-split v0.11.2 // indirect github.com/vbatts/tar-split v0.11.2 // indirect
github.com/vektah/gqlparser/v2 v2.4.4 // indirect github.com/vektah/gqlparser/v2 v2.4.5 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yashtewari/glob-intersection v0.1.0 // indirect github.com/yashtewari/glob-intersection v0.1.0 // indirect
github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect
github.com/zclconf/go-cty v1.10.0 // indirect github.com/zclconf/go-cty v1.10.0 // indirect
github.com/zclconf/go-cty-yaml v1.0.2 // indirect github.com/zclconf/go-cty-yaml v1.0.2 // indirect
go.etcd.io/bbolt v1.3.6
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect
go.opencensus.io v0.23.0 // indirect go.opencensus.io v0.23.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.7.0 // indirect go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9 golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
golang.org/x/net v0.0.0-20220516133312-45b265872317 // indirect golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e // indirect golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 // indirect golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 // indirect
google.golang.org/api v0.62.0 // indirect gonum.org/v1/gonum v0.7.0 // indirect
google.golang.org/api v0.81.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220426171045-31bebdecfb46 // indirect google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f // indirect
google.golang.org/grpc v1.47.0 // indirect google.golang.org/grpc v1.47.0 // indirect
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/neurosnap/sentences.v1 v1.0.6 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools v2.2.0+incompatible
gotest.tools/v3 v3.2.0 // indirect
helm.sh/helm/v3 v3.9.0 // indirect
k8s.io/api v0.25.0-alpha.2 // indirect
k8s.io/apiextensions-apiserver v0.24.0 // indirect
k8s.io/apimachinery v0.25.0-alpha.2 // indirect
k8s.io/apiserver v0.24.1 // indirect
k8s.io/cli-runtime v0.24.3 // indirect
k8s.io/client-go v0.25.0-alpha.2 // indirect
k8s.io/component-base v0.24.3 // indirect
k8s.io/klog/v2 v2.70.0 // indirect
k8s.io/kube-openapi v0.0.0-20220603121420-31174f50af60 // indirect
k8s.io/kubectl v0.24.3 // indirect
lukechampine.com/uint128 v1.1.1 // indirect lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.36.0 // indirect modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/ccgo/v3 v3.16.6 // indirect modernc.org/ccgo/v3 v3.16.6 // indirect
@@ -304,25 +307,7 @@ require (
modernc.org/sqlite v1.17.3 // indirect modernc.org/sqlite v1.17.3 // indirect
modernc.org/strutil v1.1.1 // indirect modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect modernc.org/token v1.0.0 // indirect
) oras.land/oras-go v1.2.0 // indirect
require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools v2.2.0+incompatible
helm.sh/helm/v3 v3.9.0 // indirect
k8s.io/api v0.24.1 // indirect
k8s.io/apiextensions-apiserver v0.24.0 // indirect
k8s.io/apimachinery v0.24.1 // indirect
k8s.io/apiserver v0.24.1 // indirect
k8s.io/cli-runtime v0.24.1 // indirect
k8s.io/client-go v0.24.1 // indirect
k8s.io/component-base v0.24.1 // indirect
k8s.io/klog/v2 v2.60.1 // indirect
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
k8s.io/kubectl v0.24.1 // indirect
oras.land/oras-go v1.1.1 // indirect
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
sigs.k8s.io/kustomize/api v0.11.4 // indirect sigs.k8s.io/kustomize/api v0.11.4 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect sigs.k8s.io/kustomize/kyaml v0.13.6 // indirect
@@ -330,9 +315,9 @@ require (
sigs.k8s.io/yaml v1.3.0 // indirect sigs.k8s.io/yaml v1.3.0 // indirect
) )
replace ( // See https://github.com/moby/moby/issues/42939#issuecomment-1114255529
// containerd main replace github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible
github.com/containerd/containerd => github.com/containerd/containerd v1.6.1-0.20220606171923-c1bcabb45419
// See https://github.com/moby/moby/issues/42939#issuecomment-1114255529 // v1.2.0 is taken from github.com/open-policy-agent/opa v0.42.0
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible // v1.2.0 incompatible with github.com/docker/docker v20.10.3-0.20220224222438-c78f6963a1c0+incompatible
) replace oras.land/oras-go => oras.land/oras-go v1.1.1

707
go.sum

File diff suppressed because it is too large Load Diff

31
goreleaser-canary.yml Normal file
View File

@@ -0,0 +1,31 @@
project_name: trivy_canary_build
builds:
-
main: cmd/trivy/main.go
binary: trivy
ldflags:
- -s -w
- "-extldflags '-static'"
- -X main.version={{.Version}}
env:
- CGO_ENABLED=0
goos:
- darwin
- linux
goarch:
- amd64
- arm64
archives:
-
format: tar.gz
name_template: "{{.ProjectName}}_{{.Version}}_{{.Os}}-{{.Arch}}"
replacements:
amd64: 64bit
arm64: ARM64
darwin: macOS
linux: Linux
files:
- README.md
- LICENSE
- contrib/*.tpl

View File

@@ -1,7 +1,7 @@
apiVersion: v2 apiVersion: v2
name: trivy name: trivy
version: 0.4.15 version: 0.4.16
appVersion: 0.27.0 appVersion: 0.29.2
description: Trivy helm chart description: Trivy helm chart
keywords: keywords:
- scanner - scanner

View File

@@ -102,5 +102,5 @@ This chart uses a PersistentVolumeClaim to reduce the number of database downloa
## Caching ## Caching
You can specify a Redis server as cache backend. This Redis server has to be already present. You can use the [bitname chart](https://bitnami.com/stack/redis/helm). You can specify a Redis server as cache backend. This Redis server has to be already present. You can use the [bitnami chart](https://bitnami.com/stack/redis/helm).
More Information about the caching backends can be found [here](https://github.com/aquasecurity/trivy#specify-cache-backend). More Information about the caching backends can be found [here](https://github.com/aquasecurity/trivy#specify-cache-backend).

View File

@@ -1,5 +1,4 @@
//go:build integration //go:build integration
// +build integration
package integration package integration
@@ -7,7 +6,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -19,10 +17,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
testcontainers "github.com/testcontainers/testcontainers-go" testcontainers "github.com/testcontainers/testcontainers-go"
"github.com/urfave/cli/v2"
"github.com/aquasecurity/trivy/pkg/clock" "github.com/aquasecurity/trivy/pkg/clock"
"github.com/aquasecurity/trivy/pkg/commands"
"github.com/aquasecurity/trivy/pkg/report" "github.com/aquasecurity/trivy/pkg/report"
) )
@@ -242,14 +238,14 @@ func TestClientServer(t *testing.T) {
}, },
} }
app, addr, cacheDir := setup(t, setupOptions{}) addr, cacheDir := setup(t, setupOptions{})
for _, c := range tests { for _, c := range tests {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
osArgs, outputFile := setupClient(t, c.args, addr, cacheDir, c.golden) osArgs, outputFile := setupClient(t, c.args, addr, cacheDir, c.golden)
// Run Trivy client //
err := app.Run(osArgs) err := execute(osArgs)
require.NoError(t, err) require.NoError(t, err)
compareReports(t, c.golden, outputFile) compareReports(t, c.golden, outputFile)
@@ -340,7 +336,7 @@ func TestClientServerWithFormat(t *testing.T) {
report.CustomTemplateFuncMap = map[string]interface{}{} report.CustomTemplateFuncMap = map[string]interface{}{}
}) })
app, addr, cacheDir := setup(t, setupOptions{}) addr, cacheDir := setup(t, setupOptions{})
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@@ -349,7 +345,7 @@ func TestClientServerWithFormat(t *testing.T) {
osArgs, outputFile := setupClient(t, tt.args, addr, cacheDir, tt.golden) osArgs, outputFile := setupClient(t, tt.args, addr, cacheDir, tt.golden)
// Run Trivy client // Run Trivy client
err := app.Run(osArgs) err := execute(osArgs)
require.NoError(t, err) require.NoError(t, err)
want, err := os.ReadFile(tt.golden) want, err := os.ReadFile(tt.golden)
@@ -386,13 +382,13 @@ func TestClientServerWithCycloneDX(t *testing.T) {
}, },
} }
app, addr, cacheDir := setup(t, setupOptions{}) addr, cacheDir := setup(t, setupOptions{})
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, outputFile := setupClient(t, tt.args, addr, cacheDir, "") osArgs, outputFile := setupClient(t, tt.args, addr, cacheDir, "")
// Run Trivy client // Run Trivy client
err := app.Run(osArgs) err := execute(osArgs)
require.NoError(t, err) require.NoError(t, err)
f, err := os.Open(outputFile) f, err := os.Open(outputFile)
@@ -450,7 +446,7 @@ func TestClientServerWithToken(t *testing.T) {
serverToken := "token" serverToken := "token"
serverTokenHeader := "Trivy-Token" serverTokenHeader := "Trivy-Token"
app, addr, cacheDir := setup(t, setupOptions{ addr, cacheDir := setup(t, setupOptions{
token: serverToken, token: serverToken,
tokenHeader: serverTokenHeader, tokenHeader: serverTokenHeader,
}) })
@@ -460,16 +456,14 @@ func TestClientServerWithToken(t *testing.T) {
osArgs, outputFile := setupClient(t, c.args, addr, cacheDir, c.golden) osArgs, outputFile := setupClient(t, c.args, addr, cacheDir, c.golden)
// Run Trivy client // Run Trivy client
err := app.Run(osArgs) err := execute(osArgs)
if c.wantErr != "" { if c.wantErr != "" {
require.NotNil(t, err, c.name) require.Error(t, err, c.name)
assert.Contains(t, err.Error(), c.wantErr, c.name) assert.Contains(t, err.Error(), c.wantErr, c.name)
return return
} else {
assert.NoError(t, err, c.name)
} }
require.NoError(t, err, c.name)
compareReports(t, c.golden, outputFile) compareReports(t, c.golden, outputFile)
}) })
} }
@@ -481,7 +475,7 @@ func TestClientServerWithRedis(t *testing.T) {
redisC, addr := setupRedis(t, ctx) redisC, addr := setupRedis(t, ctx)
// Set up Trivy server // Set up Trivy server
app, addr, cacheDir := setup(t, setupOptions{cacheBackend: addr}) addr, cacheDir := setup(t, setupOptions{cacheBackend: addr})
t.Cleanup(func() { os.RemoveAll(cacheDir) }) t.Cleanup(func() { os.RemoveAll(cacheDir) })
// Test parameters // Test parameters
@@ -494,7 +488,7 @@ func TestClientServerWithRedis(t *testing.T) {
osArgs, outputFile := setupClient(t, testArgs, addr, cacheDir, golden) osArgs, outputFile := setupClient(t, testArgs, addr, cacheDir, golden)
// Run Trivy client // Run Trivy client
err := app.Run(osArgs) err := execute(osArgs)
require.NoError(t, err) require.NoError(t, err)
compareReports(t, golden, outputFile) compareReports(t, golden, outputFile)
@@ -507,8 +501,8 @@ func TestClientServerWithRedis(t *testing.T) {
osArgs, _ := setupClient(t, testArgs, addr, cacheDir, golden) osArgs, _ := setupClient(t, testArgs, addr, cacheDir, golden)
// Run Trivy client // Run Trivy client
err := app.Run(osArgs) err := execute(osArgs)
require.NotNil(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "connect: connection refused") assert.Contains(t, err.Error(), "connect: connection refused")
}) })
} }
@@ -519,9 +513,8 @@ type setupOptions struct {
cacheBackend string cacheBackend string
} }
func setup(t *testing.T, options setupOptions) (*cli.App, string, string) { func setup(t *testing.T, options setupOptions) (string, string) {
t.Helper() t.Helper()
version := "dev"
// Set up testing DB // Set up testing DB
cacheDir := initDB(t) cacheDir := initDB(t)
@@ -534,28 +527,21 @@ func setup(t *testing.T, options setupOptions) (*cli.App, string, string) {
addr := fmt.Sprintf("localhost:%d", port) addr := fmt.Sprintf("localhost:%d", port)
go func() { go func() {
// Setup CLI App
app := commands.NewApp(version)
app.Writer = io.Discard
osArgs := setupServer(addr, options.token, options.tokenHeader, cacheDir, options.cacheBackend) osArgs := setupServer(addr, options.token, options.tokenHeader, cacheDir, options.cacheBackend)
// Run Trivy server // Run Trivy server
app.Run(osArgs) require.NoError(t, execute(osArgs))
}() }()
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
err = waitPort(ctx, addr) err = waitPort(ctx, addr)
assert.NoError(t, err) assert.NoError(t, err)
// Setup CLI App return addr, cacheDir
app := commands.NewApp(version)
app.Writer = io.Discard
return app, addr, cacheDir
} }
func setupServer(addr, token, tokenHeader, cacheDir, cacheBackend string) []string { func setupServer(addr, token, tokenHeader, cacheDir, cacheBackend string) []string {
osArgs := []string{"trivy", "--cache-dir", cacheDir, "server", "--skip-update", "--listen", addr} osArgs := []string{"--cache-dir", cacheDir, "server", "--skip-update", "--listen", addr}
if token != "" { if token != "" {
osArgs = append(osArgs, []string{"--token", token, "--token-header", tokenHeader}...) osArgs = append(osArgs, []string{"--token", token, "--token-header", tokenHeader}...)
} }
@@ -573,7 +559,7 @@ func setupClient(t *testing.T, c csArgs, addr string, cacheDir string, golden st
c.RemoteAddrOption = "--server" c.RemoteAddrOption = "--server"
} }
t.Helper() t.Helper()
osArgs := []string{"trivy", "--cache-dir", cacheDir, c.Command, c.RemoteAddrOption, "http://" + addr} osArgs := []string{"--cache-dir", cacheDir, c.Command, c.RemoteAddrOption, "http://" + addr}
if c.Format != "" { if c.Format != "" {
osArgs = append(osArgs, "--format", c.Format) osArgs = append(osArgs, "--format", c.Format)

View File

@@ -15,8 +15,6 @@ import (
"github.com/docker/docker/client" "github.com/docker/docker/client"
"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/commands"
) )
func TestDockerEngine(t *testing.T) { func TestDockerEngine(t *testing.T) {
@@ -233,16 +231,14 @@ func TestDockerEngine(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
output := filepath.Join(tmpDir, "result.json") output := filepath.Join(tmpDir, "result.json")
// run trivy osArgs := []string{"--cache-dir", cacheDir, "image",
app := commands.NewApp("dev")
trivyArgs := []string{"trivy", "--cache-dir", cacheDir, "image",
"--skip-update", "--format=json", "--output", output} "--skip-update", "--format=json", "--output", output}
if tt.ignoreUnfixed { if tt.ignoreUnfixed {
trivyArgs = append(trivyArgs, "--ignore-unfixed") osArgs = append(osArgs, "--ignore-unfixed")
} }
if len(tt.severity) != 0 { if len(tt.severity) != 0 {
trivyArgs = append(trivyArgs, osArgs = append(osArgs,
[]string{"--severity", strings.Join(tt.severity, ",")}..., []string{"--severity", strings.Join(tt.severity, ",")}...,
) )
} }
@@ -252,11 +248,12 @@ func TestDockerEngine(t *testing.T) {
assert.NoError(t, err, "failed to write .trivyignore") assert.NoError(t, err, "failed to write .trivyignore")
defer os.Remove(trivyIgnore) defer os.Remove(trivyIgnore)
} }
trivyArgs = append(trivyArgs, tt.input) osArgs = append(osArgs, tt.input)
err = app.Run(trivyArgs) // Run Trivy
err = execute(osArgs)
if tt.wantErr != "" { if tt.wantErr != "" {
require.NotNil(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), tt.wantErr, tt.name) assert.Contains(t, err.Error(), tt.wantErr, tt.name)
return return
} }

View File

@@ -4,15 +4,13 @@
package integration package integration
import ( import (
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/commands"
) )
func TestFilesystem(t *testing.T) { func TestFilesystem(t *testing.T) {
@@ -47,6 +45,14 @@ func TestFilesystem(t *testing.T) {
}, },
golden: "testdata/nodejs.json.golden", golden: "testdata/nodejs.json.golden",
}, },
{
name: "pnpm",
args: args{
securityChecks: "vuln",
input: "testdata/fixtures/fs/pnpm",
},
golden: "testdata/pnpm.json.golden",
},
{ {
name: "pip", name: "pip",
args: args{ args: args{
@@ -117,6 +123,14 @@ func TestFilesystem(t *testing.T) {
}, },
golden: "testdata/helm_testchart.json.golden", golden: "testdata/helm_testchart.json.golden",
}, },
{
name: "helm chart directory scanning with builtin policies and non string Chart name",
args: args{
securityChecks: "config",
input: "testdata/fixtures/fs/helm_badname",
},
golden: "testdata/helm_badname.json.golden",
},
{ {
name: "secrets", name: "secrets",
args: args{ args: args{
@@ -137,7 +151,7 @@ func TestFilesystem(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{
"trivy", "--cache-dir", cacheDir, "fs", "--skip-db-update", "--skip-policy-update", "-q", "--cache-dir", cacheDir, "fs", "--skip-db-update", "--skip-policy-update",
"--format", "json", "--offline-scan", "--security-checks", tt.args.securityChecks, "--format", "json", "--offline-scan", "--security-checks", tt.args.securityChecks,
} }
@@ -181,12 +195,9 @@ func TestFilesystem(t *testing.T) {
osArgs = append(osArgs, "--output", outputFile) osArgs = append(osArgs, "--output", outputFile)
osArgs = append(osArgs, tt.args.input) osArgs = append(osArgs, tt.args.input)
// Setup CLI App
app := commands.NewApp("dev")
app.Writer = io.Discard
// Run "trivy fs" // Run "trivy fs"
assert.Nil(t, app.Run(osArgs)) err := execute(osArgs)
require.NoError(t, err)
// Compare want and got // Compare want and got
compareReports(t, tt.golden, outputFile) compareReports(t, tt.golden, outputFile)

View File

@@ -6,6 +6,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"flag" "flag"
"io"
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
@@ -18,6 +19,7 @@ import (
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy-db/pkg/metadata" "github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/pkg/commands"
"github.com/aquasecurity/trivy/pkg/dbtest" "github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
) )
@@ -120,6 +122,16 @@ func readReport(t *testing.T, filePath string) types.Report {
return report return report
} }
func execute(osArgs []string) error {
// Setup CLI App
app := commands.NewApp("dev")
app.SetOut(io.Discard)
// Run Trivy
app.SetArgs(osArgs)
return app.Execute()
}
func compareReports(t *testing.T, wantFile, gotFile string) { func compareReports(t *testing.T, wantFile, gotFile string) {
want := readReport(t, wantFile) want := readReport(t, wantFile)
got := readReport(t, gotFile) got := readReport(t, gotFile)

View File

@@ -3,7 +3,6 @@
package integration package integration
import ( import (
"io"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -11,7 +10,6 @@ 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/commands"
"github.com/aquasecurity/trivy/pkg/module" "github.com/aquasecurity/trivy/pkg/module"
"github.com/aquasecurity/trivy/pkg/utils" "github.com/aquasecurity/trivy/pkg/utils"
) )
@@ -48,13 +46,9 @@ func TestModule(t *testing.T) {
filepath.Join(moduleDir, "spring4shell.wasm")) filepath.Join(moduleDir, "spring4shell.wasm"))
require.NoError(t, err) require.NoError(t, err)
// Setup CLI App
app := commands.NewApp("dev")
app.Writer = io.Discard
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{"trivy", "--cache-dir", cacheDir, "image", "--ignore-unfixed", "--format", "json", osArgs := []string{"--cache-dir", cacheDir, "image", "--ignore-unfixed", "--format", "json",
"--skip-update", "--offline-scan", "--input", tt.input} "--skip-update", "--offline-scan", "--input", tt.input}
// Set up the output file // Set up the output file
@@ -66,7 +60,8 @@ func TestModule(t *testing.T) {
osArgs = append(osArgs, []string{"--output", outputFile}...) osArgs = append(osArgs, []string{"--output", outputFile}...)
// Run Trivy // Run Trivy
assert.Nil(t, app.Run(osArgs)) err = execute(osArgs)
assert.NoError(t, err)
// Compare want and got // Compare want and got
compareReports(t, tt.golden, outputFile) compareReports(t, tt.golden, outputFile)

View File

@@ -27,8 +27,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
testcontainers "github.com/testcontainers/testcontainers-go" testcontainers "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait" "github.com/testcontainers/testcontainers-go/wait"
"github.com/aquasecurity/trivy/pkg/commands"
) )
const ( const (
@@ -235,15 +233,11 @@ func scan(t *testing.T, imageRef name.Reference, baseDir, goldenFile string, opt
return "", err return "", err
} }
// Setup CLI App osArgs := []string{"-q", "--cache-dir", cacheDir, "image", "--format", "json", "--skip-update",
app := commands.NewApp("dev")
app.Writer = io.Discard
osArgs := []string{"trivy", "--cache-dir", cacheDir, "image", "--format", "json", "--skip-update",
"--output", outputFile, imageRef.Name()} "--output", outputFile, imageRef.Name()}
// Run Trivy // Run Trivy
if err := app.Run(osArgs); err != nil { if err := execute(osArgs); err != nil {
return "", err return "", err
} }
return outputFile, nil return outputFile, nil

89
integration/sbom_test.go Normal file
View File

@@ -0,0 +1,89 @@
//go:build integration
package integration
import (
"os"
"path/filepath"
"testing"
cdx "github.com/CycloneDX/cyclonedx-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCycloneDX(t *testing.T) {
type args struct {
input string
format string
artifactType string
}
tests := []struct {
name string
args args
golden string
}{
{
name: "centos7-bom by trivy",
args: args{
input: "testdata/fixtures/sbom/centos-7-cyclonedx.json",
format: "cyclonedx",
artifactType: "cyclonedx",
},
golden: "testdata/centos-7-cyclonedx.json.golden",
},
{
name: "fluentd-multiple-lockfiles-bom by trivy",
args: args{
input: "testdata/fixtures/sbom/fluentd-multiple-lockfiles-cyclonedx.json",
format: "cyclonedx",
artifactType: "cyclonedx",
},
golden: "testdata/fluentd-multiple-lockfiles-cyclonedx.json.golden",
},
}
// Set up testing DB
cacheDir := initDB(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := []string{
"--cache-dir", cacheDir, "sbom", "-q", "--skip-db-update", "--format", tt.args.format,
}
// Setup the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
if *update {
outputFile = tt.golden
}
osArgs = append(osArgs, "--output", outputFile)
osArgs = append(osArgs, tt.args.input)
// Run "trivy sbom"
err := execute(osArgs)
assert.NoError(t, err)
// Compare want and got
want := decodeCycloneDX(t, tt.golden)
got := decodeCycloneDX(t, outputFile)
assert.Equal(t, want, got)
})
}
}
func decodeCycloneDX(t *testing.T, filePath string) *cdx.BOM {
f, err := os.Open(filePath)
require.NoError(t, err)
defer f.Close()
bom := cdx.NewBOM()
decoder := cdx.NewBOMDecoder(f, cdx.BOMFileFormatJSON)
err = decoder.Decode(bom)
require.NoError(t, err)
bom.Metadata.Timestamp = ""
return bom
}

View File

@@ -1,18 +1,15 @@
//go:build integration //go:build integration
// +build integration
package integration package integration
import ( import (
"io"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/commands"
) )
func TestTar(t *testing.T) { func TestTar(t *testing.T) {
@@ -264,13 +261,9 @@ func TestTar(t *testing.T) {
// Set a temp dir so that modules will not be loaded // Set a temp dir so that modules will not be loaded
t.Setenv("XDG_DATA_HOME", cacheDir) t.Setenv("XDG_DATA_HOME", cacheDir)
// Setup CLI App
app := commands.NewApp("dev")
app.Writer = io.Discard
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{"trivy", "--cache-dir", cacheDir, "image", "--format", tt.testArgs.Format, "--skip-update"} osArgs := []string{"--cache-dir", cacheDir, "image", "-q", "--format", tt.testArgs.Format, "--skip-update"}
if tt.testArgs.IgnoreUnfixed { if tt.testArgs.IgnoreUnfixed {
osArgs = append(osArgs, "--ignore-unfixed") osArgs = append(osArgs, "--ignore-unfixed")
@@ -310,7 +303,8 @@ func TestTar(t *testing.T) {
osArgs = append(osArgs, []string{"--output", outputFile}...) osArgs = append(osArgs, []string{"--output", outputFile}...)
// Run Trivy // Run Trivy
assert.Nil(t, app.Run(osArgs)) err := execute(osArgs)
require.NoError(t, err)
// Compare want and got // Compare want and got
compareReports(t, tt.golden, outputFile) compareReports(t, tt.golden, outputFile)

View File

@@ -0,0 +1,526 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"metadata": {
"timestamp": "2022-07-03T08:45:54+00:00",
"tools": [
{
"vendor": "aquasecurity",
"name": "trivy",
"version": "dev"
}
],
"component": {
"bom-ref": "urn:uuid:1455c02d-64ca-453e-a5df-ddfb70a7c804/1",
"type": "container",
"name": "integration/testdata/fixtures/images/centos-7.tar.gz"
}
},
"vulnerabilities": [
{
"id": "CVE-2019-18276",
"ratings": [
{
"source": {
"name": "cbl-mariner"
},
"severity": "high"
},
{
"source": {
"name": "nvd"
},
"score": 7.2,
"severity": "high",
"method": "CVSSv2",
"vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C"
},
{
"source": {
"name": "nvd"
},
"score": 7.8,
"severity": "high",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "oracle-oval"
},
"severity": "low"
},
{
"source": {
"name": "photon"
},
"severity": "high"
},
{
"source": {
"name": "redhat"
},
"score": 7.8,
"severity": "low",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "ubuntu"
},
"severity": "low"
}
],
"cwes": [
273
],
"description": "An issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11. By default, if Bash is run with its effective UID not equal to its real UID, it will drop privileges by setting its effective UID to its real UID. However, it does so incorrectly. On Linux and other systems that support \"saved UID\" functionality, the saved UID is not dropped. An attacker with command execution in the shell can use \"enable -f\" for runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore regains privileges. However, binaries running with an effective UID of 0 are unaffected.",
"advisories": [
{
"url": "http://packetstormsecurity.com/files/155498/Bash-5.0-Patch-11-Privilege-Escalation.html"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2019-18276"
},
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18276"
},
{
"url": "https://github.com/bminor/bash/commit/951bdaad7a18cc0dc1036bba86b18b90874d39ff"
},
{
"url": "https://linux.oracle.com/cve/CVE-2019-18276.html"
},
{
"url": "https://linux.oracle.com/errata/ELSA-2021-1679.html"
},
{
"url": "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E"
},
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18276"
},
{
"url": "https://security.gentoo.org/glsa/202105-34"
},
{
"url": "https://security.netapp.com/advisory/ntap-20200430-0003/"
},
{
"url": "https://www.youtube.com/watch?v=-wGtxJ8opa8"
}
],
"published": "2019-11-28T01:15:00+00:00",
"updated": "2021-05-26T12:15:00+00:00",
"affects": [
{
"ref": "urn:cdx:1455c02d-64ca-453e-a5df-ddfb70a7c804/1#pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64\u0026distro=centos-7.6.1810",
"versions": [
{
"version": "4.2.46-31.el7",
"status": "affected"
}
]
}
]
},
{
"id": "CVE-2019-1559",
"ratings": [
{
"source": {
"name": "amazon"
},
"severity": "medium"
},
{
"source": {
"name": "arch-linux"
},
"severity": "medium"
},
{
"source": {
"name": "nvd"
},
"score": 4.3,
"severity": "medium",
"method": "CVSSv2",
"vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N"
},
{
"source": {
"name": "nvd"
},
"score": 5.9,
"severity": "medium",
"method": "CVSSv3",
"vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
},
{
"source": {
"name": "oracle-oval"
},
"severity": "medium"
},
{
"source": {
"name": "redhat"
},
"score": 5.9,
"severity": "medium",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
},
{
"source": {
"name": "ubuntu"
},
"severity": "medium"
}
],
"cwes": [
203
],
"description": "If an application encounters a fatal protocol error and then calls SSL_shutdown() twice (once to send a close_notify, and once to receive one) then OpenSSL can respond differently to the calling application if a 0 byte record is received with invalid padding compared to if a 0 byte record is received with an invalid MAC. If the application then behaves differently based on that in a way that is detectable to the remote peer, then this amounts to a padding oracle that could be used to decrypt data. In order for this to be exploitable \"non-stitched\" ciphersuites must be in use. Stitched ciphersuites are optimised implementations of certain commonly used ciphersuites. Also the application must call SSL_shutdown() twice even if a protocol error has occurred (applications should not do this but some do anyway). Fixed in OpenSSL 1.0.2r (Affected 1.0.2-1.0.2q).",
"advisories": [
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-03/msg00041.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00019.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00046.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00047.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-05/msg00049.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00080.html"
},
{
"url": "http://www.securityfocus.com/bid/107174"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:2304"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:2437"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:2439"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:2471"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3929"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3931"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2019-1559"
},
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1559"
},
{
"url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=e9bbefbf0f24c57645e7ad6a5a71ae649d18ac8e"
},
{
"url": "https://github.com/RUB-NDS/TLS-Padding-Oracles"
},
{
"url": "https://kc.mcafee.com/corporate/index?page=content\u0026id=SB10282"
},
{
"url": "https://linux.oracle.com/cve/CVE-2019-1559.html"
},
{
"url": "https://linux.oracle.com/errata/ELSA-2019-2471.html"
},
{
"url": "https://lists.debian.org/debian-lts-announce/2019/03/msg00003.html"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EWC42UXL5GHTU5G77VKBF6JYUUNGSHOM/"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Y3IVFGSERAZLNJCK35TEM2R4726XIH3Z/"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZBEV5QGDRFUZDMNECFXUSN5FMYOZDE4V/"
},
{
"url": "https://security.gentoo.org/glsa/201903-10"
},
{
"url": "https://security.netapp.com/advisory/ntap-20190301-0001/"
},
{
"url": "https://security.netapp.com/advisory/ntap-20190301-0002/"
},
{
"url": "https://security.netapp.com/advisory/ntap-20190423-0002/"
},
{
"url": "https://support.f5.com/csp/article/K18549143"
},
{
"url": "https://support.f5.com/csp/article/K18549143?utm_source=f5support\u0026amp;utm_medium=RSS"
},
{
"url": "https://ubuntu.com/security/notices/USN-3899-1"
},
{
"url": "https://ubuntu.com/security/notices/USN-4376-2"
},
{
"url": "https://usn.ubuntu.com/3899-1/"
},
{
"url": "https://usn.ubuntu.com/4376-2/"
},
{
"url": "https://www.debian.org/security/2019/dsa-4400"
},
{
"url": "https://www.openssl.org/news/secadv/20190226.txt"
},
{
"url": "https://www.oracle.com/security-alerts/cpujan2020.html"
},
{
"url": "https://www.oracle.com/security-alerts/cpujan2021.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html"
},
{
"url": "https://www.tenable.com/security/tns-2019-02"
},
{
"url": "https://www.tenable.com/security/tns-2019-03"
}
],
"published": "2019-02-27T23:29:00+00:00",
"updated": "2021-01-20T15:15:00+00:00",
"affects": [
{
"ref": "urn:cdx:1455c02d-64ca-453e-a5df-ddfb70a7c804/1#pkg:rpm/centos/openssl-libs@1:1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810",
"versions": [
{
"version": "1:1.0.2k-16.el7",
"status": "affected"
}
]
}
]
},
{
"id": "CVE-2018-0734",
"ratings": [
{
"source": {
"name": "amazon"
},
"severity": "medium"
},
{
"source": {
"name": "arch-linux"
},
"severity": "low"
},
{
"source": {
"name": "cbl-mariner"
},
"severity": "medium"
},
{
"source": {
"name": "nvd"
},
"score": 4.3,
"severity": "medium",
"method": "CVSSv2",
"vector": "AV:N/AC:M/Au:N/C:P/I:N/A:N"
},
{
"source": {
"name": "nvd"
},
"score": 5.9,
"severity": "medium",
"method": "CVSSv3",
"vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
},
{
"source": {
"name": "oracle-oval"
},
"severity": "low"
},
{
"source": {
"name": "photon"
},
"severity": "medium"
},
{
"source": {
"name": "redhat"
},
"score": 5.1,
"severity": "low",
"method": "CVSSv3",
"vector": "CVSS:3.0/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N"
},
{
"source": {
"name": "ubuntu"
},
"severity": "low"
}
],
"cwes": [
327
],
"description": "The OpenSSL DSA signature algorithm has been shown to be vulnerable to a timing side channel attack. An attacker could use variations in the signing algorithm to recover the private key. Fixed in OpenSSL 1.1.1a (Affected 1.1.1). Fixed in OpenSSL 1.1.0j (Affected 1.1.0-1.1.0i). Fixed in OpenSSL 1.0.2q (Affected 1.0.2-1.0.2p).",
"advisories": [
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00030.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-07/msg00056.html"
},
{
"url": "http://www.securityfocus.com/bid/105758"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:2304"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3700"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3932"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3933"
},
{
"url": "https://access.redhat.com/errata/RHSA-2019:3935"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2018-0734"
},
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0734"
},
{
"url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=43e6a58d4991a451daf4891ff05a48735df871ac"
},
{
"url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=8abfe72e8c1de1b95f50aa0d9134803b4d00070f"
},
{
"url": "https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=ef11e19d1365eea2b1851e6f540a0bf365d303e7"
},
{
"url": "https://linux.oracle.com/cve/CVE-2018-0734.html"
},
{
"url": "https://linux.oracle.com/errata/ELSA-2019-3700.html"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EWC42UXL5GHTU5G77VKBF6JYUUNGSHOM/"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/Y3IVFGSERAZLNJCK35TEM2R4726XIH3Z/"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZBEV5QGDRFUZDMNECFXUSN5FMYOZDE4V/"
},
{
"url": "https://nodejs.org/en/blog/vulnerability/november-2018-security-releases/"
},
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-0734"
},
{
"url": "https://security.netapp.com/advisory/ntap-20181105-0002/"
},
{
"url": "https://security.netapp.com/advisory/ntap-20190118-0002/"
},
{
"url": "https://security.netapp.com/advisory/ntap-20190423-0002/"
},
{
"url": "https://ubuntu.com/security/notices/USN-3840-1"
},
{
"url": "https://usn.ubuntu.com/3840-1/"
},
{
"url": "https://www.debian.org/security/2018/dsa-4348"
},
{
"url": "https://www.debian.org/security/2018/dsa-4355"
},
{
"url": "https://www.openssl.org/news/secadv/20181030.txt"
},
{
"url": "https://www.oracle.com/security-alerts/cpuapr2020.html"
},
{
"url": "https://www.oracle.com/security-alerts/cpujan2020.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpujan2019-5072801.html"
},
{
"url": "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html"
},
{
"url": "https://www.tenable.com/security/tns-2018-16"
},
{
"url": "https://www.tenable.com/security/tns-2018-17"
}
],
"published": "2018-10-30T12:29:00+00:00",
"updated": "2020-08-24T17:37:00+00:00",
"affects": [
{
"ref": "urn:cdx:1455c02d-64ca-453e-a5df-ddfb70a7c804/1#pkg:rpm/centos/openssl-libs@1:1.0.2k-16.el7?arch=x86_64\u0026distro=centos-7.6.1810",
"versions": [
{
"version": "1:1.0.2k-16.el7",
"status": "affected"
}
]
}
]
}
]
}

View File

@@ -5,7 +5,8 @@
"Metadata": { "Metadata": {
"OS": { "OS": {
"Family": "debian", "Family": "debian",
"Name": "9.9" "Name": "9.9",
"Eosl": true
}, },
"ImageID": "sha256:f26939cc87ef44a6fc554eedd0a976ab30b5bc2769d65d2e986b6c5f1fd4053d", "ImageID": "sha256:f26939cc87ef44a6fc554eedd0a976ab30b5bc2769d65d2e986b6c5f1fd4053d",
"DiffIDs": [ "DiffIDs": [

View File

@@ -5,7 +5,8 @@
"Metadata": { "Metadata": {
"OS": { "OS": {
"Family": "debian", "Family": "debian",
"Name": "9.9" "Name": "9.9",
"Eosl": true
}, },
"ImageID": "sha256:7f04a8d247173b1f2546d22913af637bbab4e7411e00ae6207da8d94c445750d", "ImageID": "sha256:7f04a8d247173b1f2546d22913af637bbab4e7411e00ae6207da8d94c445750d",
"DiffIDs": [ "DiffIDs": [

View File

@@ -5,7 +5,8 @@
"Metadata": { "Metadata": {
"OS": { "OS": {
"Family": "debian", "Family": "debian",
"Name": "9.9" "Name": "9.9",
"Eosl": true
}, },
"ImageID": "sha256:6fcac2cc8a710f21577b5bbd534e0bfc841c0cca569b57182ba19054696cddda", "ImageID": "sha256:6fcac2cc8a710f21577b5bbd534e0bfc841c0cca569b57182ba19054696cddda",
"DiffIDs": [ "DiffIDs": [

View File

@@ -0,0 +1,3 @@
apiVersion: v2
name: 1001
version: 1.0.0

19
integration/testdata/fixtures/fs/pnpm/pnpm-lock.yaml generated vendored Normal file
View File

@@ -0,0 +1,19 @@
lockfileVersion: 5.4
specifiers:
jquery: 3.3.9
lodash: 4.17.4
dependencies:
jquery: 3.3.9
lodash: 4.17.4
packages:
/jquery/3.3.9:
resolution: {integrity: sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ==}
dev: false
/lodash/4.17.4:
resolution: {integrity: sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=}
dev: false

View File

@@ -0,0 +1,140 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:1455c02d-64ca-453e-a5df-ddfb70a7c804",
"version": 1,
"metadata": {
"timestamp": "2022-06-14T15:08:48+00:00",
"tools": [
{
"vendor": "aquasecurity",
"name": "trivy",
"version": "dev"
}
],
"component": {
"bom-ref": "d0d41e30-9650-489d-948d-425ff2ed63d2",
"type": "container",
"name": "integration/testdata/fixtures/images/centos-7.tar.gz",
"properties": [
{
"name": "aquasecurity:trivy:SchemaVersion",
"value": "2"
},
{
"name": "aquasecurity:trivy:ImageID",
"value": "sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a"
}
]
}
},
"components": [
{
"bom-ref": "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810",
"type": "library",
"name": "bash",
"version": "4.2.46-31.el7",
"licenses": [
{
"expression": "GPLv3+"
}
],
"purl": "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810",
"properties": [
{
"name": "aquasecurity:trivy:SrcName",
"value": "bash"
},
{
"name": "aquasecurity:trivy:SrcVersion",
"value": "4.2.46"
},
{
"name": "aquasecurity:trivy:SrcRelease",
"value": "31.el7"
},
{
"name": "aquasecurity:trivy:LayerDigest",
"value": "sha256:ac9208207adaac3a48e54a4dc6b49c69e78c3072d2b3add7efdabf814db2133b"
},
{
"name": "aquasecurity:trivy:LayerDiffID",
"value": "sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a"
}
]
},
{
"bom-ref": "pkg:rpm/centos/openssl-libs@1:1.0.2k-16.el7?arch=x86_64&distro=centos-7.6.1810",
"type": "library",
"name": "openssl-libs",
"version": "1:1.0.2k-16.el7",
"licenses": [
{
"expression": "OpenSSL"
}
],
"purl": "pkg:rpm/centos/openssl-libs@1:1.0.2k-16.el7?arch=x86_64&distro=centos-7.6.1810",
"properties": [
{
"name": "aquasecurity:trivy:SrcName",
"value": "openssl"
},
{
"name": "aquasecurity:trivy:SrcVersion",
"value": "1.0.2k"
},
{
"name": "aquasecurity:trivy:SrcRelease",
"value": "16.el7"
},
{
"name": "aquasecurity:trivy:SrcEpoch",
"value": "1"
},
{
"name": "aquasecurity:trivy:LayerDigest",
"value": "sha256:ac9208207adaac3a48e54a4dc6b49c69e78c3072d2b3add7efdabf814db2133b"
},
{
"name": "aquasecurity:trivy:LayerDiffID",
"value": "sha256:89169d87dbe2b72ba42bfbb3579c957322baca28e03a1e558076542a1c1b2b4a"
}
]
},
{
"bom-ref": "0175f732-df9d-4bb8-9f56-870898e3ff89",
"type": "operating-system",
"name": "centos",
"version": "7.6.1810",
"properties": [
{
"name": "aquasecurity:trivy:Type",
"value": "centos"
},
{
"name": "aquasecurity:trivy:Class",
"value": "os-pkgs"
}
]
}
],
"dependencies": [
{
"ref": "0175f732-df9d-4bb8-9f56-870898e3ff89",
"dependsOn": [
"pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810",
"pkg:rpm/centos/openssl-libs@1:1.0.2k-16.el7?arch=x86_64&distro=centos-7.6.1810"
]
},
{
"ref": "d0d41e30-9650-489d-948d-425ff2ed63d2",
"dependsOn": [
"0175f732-df9d-4bb8-9f56-870898e3ff89"
]
}
]
}

View File

@@ -0,0 +1,169 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:31ee662c-480e-4f63-9765-23ea8afc754d",
"version": 1,
"metadata": {
"timestamp": "2022-06-14T15:10:14+00:00",
"tools": [
{
"vendor": "aquasecurity",
"name": "trivy",
"version": "dev"
}
],
"component": {
"bom-ref": "95de56ee-980c-413d-8f68-6c674dc3e9d1",
"type": "container",
"name": "integration/testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz",
"properties": [
{
"name": "aquasecurity:trivy:SchemaVersion",
"value": "2"
},
{
"name": "aquasecurity:trivy:ImageID",
"value": "sha256:5a992077baba51b97f27591a10d54d2f2723dc9c81a3fe419e261023f2554933"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:831c5620387fb9efec59fc82a42b948546c6be601e3ab34a87108ecf852aa15f"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:02874b2b269dea8dde0f7edb4c9906904dfe38a09de1a214f20c650cfb15c60e"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:3752e1f6fd759c795c13aff2c93c081529366e27635ba6621e849b0f9cfc77f0"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:75e43d55939745950bc3f8fad56c5834617c4339f0f54755e69a0dd5372624e9"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:788c00e2cfc8f2a018ae4344ccf0b2c226ebd756d7effd1ce50eea1a4252cd89"
},
{
"name": "aquasecurity:trivy:DiffID",
"value": "sha256:25165eb51d15842f870f97873e0a58409d5e860e6108e3dd829bd10e484c0065"
}
]
}
},
"components": [
{
"bom-ref": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2",
"type": "library",
"name": "bash",
"version": "5.0-4",
"purl": "pkg:deb/debian/bash@5.0-4?distro=debian-10.2",
"properties": [
{
"name": "aquasecurity:trivy:SrcName",
"value": "bash"
},
{
"name": "aquasecurity:trivy:SrcVersion",
"value": "5.0-4"
},
{
"name": "aquasecurity:trivy:LayerDigest",
"value": "sha256:000eee12ec04cc914bf96e8f5dee7767510c2aca3816af6078bd9fbe3150920c"
},
{
"name": "aquasecurity:trivy:LayerDiffID",
"value": "sha256:831c5620387fb9efec59fc82a42b948546c6be601e3ab34a87108ecf852aa15f"
}
]
},
{
"bom-ref": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2",
"type": "library",
"name": "libidn2-0",
"version": "2.0.5-1",
"purl": "pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2",
"properties": [
{
"name": "aquasecurity:trivy:SrcName",
"value": "libidn2"
},
{
"name": "aquasecurity:trivy:SrcVersion",
"value": "2.0.5-1"
},
{
"name": "aquasecurity:trivy:LayerDigest",
"value": "sha256:000eee12ec04cc914bf96e8f5dee7767510c2aca3816af6078bd9fbe3150920c"
},
{
"name": "aquasecurity:trivy:LayerDiffID",
"value": "sha256:831c5620387fb9efec59fc82a42b948546c6be601e3ab34a87108ecf852aa15f"
}
]
},
{
"bom-ref": "353f2470-9c8b-4647-9d0d-96d893838dc8",
"type": "operating-system",
"name": "debian",
"version": "10.2",
"properties": [
{
"name": "aquasecurity:trivy:Type",
"value": "debian"
},
{
"name": "aquasecurity:trivy:Class",
"value": "os-pkgs"
}
]
},
{
"bom-ref": "pkg:gem/activesupport@6.0.2.1?file_path=var%2Flib%2Fgems%2F2.5.0%2Fspecifications%2Factivesupport-6.0.2.1.gemspec",
"type": "library",
"name": "activesupport",
"version": "6.0.2.1",
"licenses": [
{
"expression": "MIT"
}
],
"purl": "pkg:gem/activesupport@6.0.2.1",
"properties": [
{
"name": "aquasecurity:trivy:FilePath",
"value": "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec"
},
{
"name": "aquasecurity:trivy:LayerDigest",
"value": "sha256:a8877cad19f14a7044524a145ce33170085441a7922458017db1631dcd5f7602"
},
{
"name": "aquasecurity:trivy:LayerDiffID",
"value": "sha256:75e43d55939745950bc3f8fad56c5834617c4339f0f54755e69a0dd5372624e9"
},
{
"name": "aquasecurity:trivy:Type",
"value": "gemspec"
}
]
}
],
"dependencies": [
{
"ref": "353f2470-9c8b-4647-9d0d-96d893838dc8",
"dependsOn": [
"pkg:deb/debian/bash@5.0-4?distro=debian-10.2",
"pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2"
]
},
{
"ref": "95de56ee-980c-413d-8f68-6c674dc3e9d1",
"dependsOn": [
"353f2470-9c8b-4647-9d0d-96d893838dc8",
"pkg:gem/activesupport@6.0.2.1?file_path=var%2Flib%2Fgems%2F2.5.0%2Fspecifications%2Factivesupport-6.0.2.1.gemspec"
]
}
]
}

View File

@@ -0,0 +1,346 @@
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"metadata": {
"timestamp": "2022-07-03T08:45:54+00:00",
"tools": [
{
"vendor": "aquasecurity",
"name": "trivy",
"version": "dev"
}
],
"component": {
"bom-ref": "urn:uuid:31ee662c-480e-4f63-9765-23ea8afc754d/1",
"type": "container",
"name": "integration/testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz"
}
},
"vulnerabilities": [
{
"id": "CVE-2020-8165",
"source": {
"name": "ghsa",
"url": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Arubygems"
},
"ratings": [
{
"source": {
"name": "ghsa"
},
"severity": "high"
},
{
"source": {
"name": "nvd"
},
"score": 7.5,
"severity": "high",
"method": "CVSSv2",
"vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"
},
{
"source": {
"name": "nvd"
},
"score": 9.8,
"severity": "critical",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "redhat"
},
"score": 9.8,
"severity": "high",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
}
],
"cwes": [
502
],
"description": "A deserialization of untrusted data vulnerability exists in rails \u003c 5.2.4.3, rails \u003c 6.0.3.1 that can allow an attacker to unmarshal user-provided objects in MemCacheStore and RedisCacheStore potentially resulting in an RCE.",
"advisories": [
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2020-10/msg00031.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2020-10/msg00034.html"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2020-8165"
},
{
"url": "https://github.com/advisories/GHSA-2p68-f74v-9wc6"
},
{
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/activesupport/CVE-2020-8165.yml"
},
{
"url": "https://groups.google.com/forum/#!msg/rubyonrails-security/bv6fW4S0Y1c/KnkEqM7AAQAJ"
},
{
"url": "https://groups.google.com/forum/#!topic/rubyonrails-security/bv6fW4S0Y1c"
},
{
"url": "https://groups.google.com/g/rubyonrails-security/c/bv6fW4S0Y1c"
},
{
"url": "https://hackerone.com/reports/413388"
},
{
"url": "https://lists.debian.org/debian-lts-announce/2020/06/msg00022.html"
},
{
"url": "https://lists.debian.org/debian-lts-announce/2020/07/msg00013.html"
},
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-8165"
},
{
"url": "https://weblog.rubyonrails.org/2020/5/18/Rails-5-2-4-3-and-6-0-3-1-have-been-released/"
},
{
"url": "https://www.debian.org/security/2020/dsa-4766"
}
],
"published": "2020-06-19T18:15:00+00:00",
"updated": "2020-10-17T12:15:00+00:00",
"affects": [
{
"ref": "urn:cdx:31ee662c-480e-4f63-9765-23ea8afc754d/1#pkg:gem/activesupport@6.0.2.1?file_path=var%2Flib%2Fgems%2F2.5.0%2Fspecifications%2Factivesupport-6.0.2.1.gemspec",
"versions": [
{
"version": "6.0.2.1",
"status": "affected"
}
]
}
]
},
{
"id": "CVE-2019-18276",
"source": {
"name": "debian",
"url": "https://salsa.debian.org/security-tracker-team/security-tracker"
},
"ratings": [
{
"source": {
"name": "cbl-mariner"
},
"severity": "high"
},
{
"source": {
"name": "nvd"
},
"score": 7.2,
"severity": "high",
"method": "CVSSv2",
"vector": "AV:L/AC:L/Au:N/C:C/I:C/A:C"
},
{
"source": {
"name": "nvd"
},
"score": 7.8,
"severity": "high",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "oracle-oval"
},
"severity": "low"
},
{
"source": {
"name": "photon"
},
"severity": "high"
},
{
"source": {
"name": "redhat"
},
"score": 7.8,
"severity": "low",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "ubuntu"
},
"severity": "low"
}
],
"cwes": [
273
],
"description": "An issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11. By default, if Bash is run with its effective UID not equal to its real UID, it will drop privileges by setting its effective UID to its real UID. However, it does so incorrectly. On Linux and other systems that support \"saved UID\" functionality, the saved UID is not dropped. An attacker with command execution in the shell can use \"enable -f\" for runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore regains privileges. However, binaries running with an effective UID of 0 are unaffected.",
"advisories": [
{
"url": "http://packetstormsecurity.com/files/155498/Bash-5.0-Patch-11-Privilege-Escalation.html"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2019-18276"
},
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18276"
},
{
"url": "https://github.com/bminor/bash/commit/951bdaad7a18cc0dc1036bba86b18b90874d39ff"
},
{
"url": "https://linux.oracle.com/cve/CVE-2019-18276.html"
},
{
"url": "https://linux.oracle.com/errata/ELSA-2021-1679.html"
},
{
"url": "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772@%3Cdev.mina.apache.org%3E"
},
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-18276"
},
{
"url": "https://security.gentoo.org/glsa/202105-34"
},
{
"url": "https://security.netapp.com/advisory/ntap-20200430-0003/"
},
{
"url": "https://www.youtube.com/watch?v=-wGtxJ8opa8"
}
],
"published": "2019-11-28T01:15:00+00:00",
"updated": "2021-05-26T12:15:00+00:00",
"affects": [
{
"ref": "urn:cdx:31ee662c-480e-4f63-9765-23ea8afc754d/1#pkg:deb/debian/bash@5.0-4?distro=debian-10.2",
"versions": [
{
"version": "5.0-4",
"status": "affected"
}
]
}
]
},
{
"id": "CVE-2019-18224",
"source": {
"name": "debian",
"url": "https://salsa.debian.org/security-tracker-team/security-tracker"
},
"ratings": [
{
"source": {
"name": "amazon"
},
"severity": "medium"
},
{
"source": {
"name": "nvd"
},
"score": 7.5,
"severity": "high",
"method": "CVSSv2",
"vector": "AV:N/AC:L/Au:N/C:P/I:P/A:P"
},
{
"source": {
"name": "nvd"
},
"score": 9.8,
"severity": "critical",
"method": "CVSSv31",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
},
{
"source": {
"name": "redhat"
},
"score": 5.6,
"severity": "medium",
"method": "CVSSv3",
"vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
},
{
"source": {
"name": "ubuntu"
},
"severity": "medium"
}
],
"cwes": [
787
],
"description": "idn2_to_ascii_4i in lib/lookup.c in GNU libidn2 before 2.1.1 has a heap-based buffer overflow via a long domain string.",
"advisories": [
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-12/msg00008.html"
},
{
"url": "http://lists.opensuse.org/opensuse-security-announce/2019-12/msg00009.html"
},
{
"url": "https://access.redhat.com/security/cve/CVE-2019-18224"
},
{
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12420"
},
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-18224"
},
{
"url": "https://github.com/libidn/libidn2/commit/e4d1558aa2c1c04a05066ee8600f37603890ba8c"
},
{
"url": "https://github.com/libidn/libidn2/compare/libidn2-2.1.0...libidn2-2.1.1"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/JDQVQ2XPV5BTZUFINT7AFJSKNNBVURNJ/"
},
{
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/MINU5RKDFE6TKAFY5DRFN3WSFDS4DYVS/"
},
{
"url": "https://seclists.org/bugtraq/2020/Feb/4"
},
{
"url": "https://security.gentoo.org/glsa/202003-63"
},
{
"url": "https://ubuntu.com/security/notices/USN-4168-1"
},
{
"url": "https://usn.ubuntu.com/4168-1/"
},
{
"url": "https://www.debian.org/security/2020/dsa-4613"
}
],
"published": "2019-10-21T17:15:00+00:00",
"updated": "2019-10-29T19:15:00+00:00",
"affects": [
{
"ref": "urn:cdx:31ee662c-480e-4f63-9765-23ea8afc754d/1#pkg:deb/debian/libidn2-0@2.0.5-1?distro=debian-10.2",
"versions": [
{
"version": "2.0.5-1",
"status": "affected"
}
]
}
]
}
]
}

View File

@@ -0,0 +1,17 @@
{
"SchemaVersion": 2,
"ArtifactName": "testdata/fixtures/fs/helm_badname",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
}
}

175
integration/testdata/pnpm.json.golden vendored Normal file
View File

@@ -0,0 +1,175 @@
{
"SchemaVersion": 2,
"ArtifactName": "testdata/fixtures/fs/pnpm",
"ArtifactType": "filesystem",
"Results": [
{
"Target": "pnpm-lock.yaml",
"Class": "lang-pkgs",
"Type": "pnpm",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2019-11358",
"PkgID": "jquery@3.3.9",
"PkgName": "jquery",
"InstalledVersion": "3.3.9",
"FixedVersion": "3.4.0",
"Layer": {},
"SeveritySource": "ghsa",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-11358",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Npm",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm"
},
"Title": "jquery: Prototype pollution in object's prototype leading to denial of service, remote code execution, or property injection",
"Description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.",
"Severity": "MEDIUM",
"CweIDs": [
"CWE-79"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N",
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"V2Score": 4.3,
"V3Score": 6.1
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"V3Score": 5.6
}
},
"References": [
"http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html",
"http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00025.html",
"http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html",
"http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html",
"http://packetstormsecurity.com/files/156743/OctoberCMS-Insecure-Dependencies.html",
"http://seclists.org/fulldisclosure/2019/May/10",
"http://seclists.org/fulldisclosure/2019/May/11",
"http://seclists.org/fulldisclosure/2019/May/13",
"http://www.openwall.com/lists/oss-security/2019/06/03/2",
"http://www.securityfocus.com/bid/108023",
"https://access.redhat.com/errata/RHBA-2019:1570",
"https://access.redhat.com/errata/RHSA-2019:1456",
"https://access.redhat.com/errata/RHSA-2019:2587",
"https://access.redhat.com/errata/RHSA-2019:3023",
"https://access.redhat.com/errata/RHSA-2019:3024",
"https://access.redhat.com/security/cve/CVE-2019-11358",
"https://backdropcms.org/security/backdrop-sa-core-2019-009",
"https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358",
"https://github.com/DanielRuf/snyk-js-jquery-174006?files=1",
"https://github.com/advisories/GHSA-6c3j-c64m-qhgq",
"https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b",
"https://github.com/jquery/jquery/pull/4333",
"https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434",
"https://hackerone.com/reports/454365",
"https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44601",
"https://linux.oracle.com/cve/CVE-2019-11358.html",
"https://linux.oracle.com/errata/ELSA-2020-4847.html",
"https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/519eb0fd45642dcecd9ff74cb3e71c20a4753f7d82e2f07864b5108f@%3Cdev.drill.apache.org%3E",
"https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/b0656d359c7d40ec9f39c8cc61bca66802ef9a2a12ee199f5b0c1442@%3Cdev.drill.apache.org%3E",
"https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E",
"https://lists.apache.org/thread.html/ba79cf1658741e9f146e4c59b50aee56656ea95d841d358d006c18b6@%3Ccommits.roller.apache.org%3E",
"https://lists.apache.org/thread.html/bcce5a9c532b386c68dab2f6b3ce8b0cc9b950ec551766e76391caa3@%3Ccommits.nifi.apache.org%3E",
"https://lists.apache.org/thread.html/f9bc3e55f4e28d1dcd1a69aae6d53e609a758e34d2869b4d798e13cc@%3Cissues.drill.apache.org%3E",
"https://lists.apache.org/thread.html/r2041a75d3fc09dec55adfd95d598b38d22715303f65c997c054844c9@%3Cissues.flink.apache.org%3E",
"https://lists.apache.org/thread.html/r2baacab6e0acb5a2092eb46ae04fd6c3e8277b4fd79b1ffb7f3254fa@%3Cissues.flink.apache.org%3E",
"https://lists.apache.org/thread.html/r38f0d1aa3c923c22977fe7376508f030f22e22c1379fbb155bf29766@%3Cdev.syncope.apache.org%3E",
"https://lists.apache.org/thread.html/r41b5bfe009c845f67d4f68948cc9419ac2d62e287804aafd72892b08@%3Cissues.flink.apache.org%3E",
"https://lists.apache.org/thread.html/r7aac081cbddb6baa24b75e74abf0929bf309b176755a53e3ed810355@%3Cdev.flink.apache.org%3E",
"https://lists.apache.org/thread.html/r7d64895cc4dff84d0becfc572b20c0e4bf9bfa7b10c6f5f73e783734@%3Cdev.storm.apache.org%3E",
"https://lists.apache.org/thread.html/r7e8ebccb7c022e41295f6fdb7b971209b83702339f872ddd8cf8bf73@%3Cissues.flink.apache.org%3E",
"https://lists.apache.org/thread.html/rac25da84ecdcd36f6de5ad0d255f4e967209bbbebddb285e231da37d@%3Cissues.flink.apache.org%3E",
"https://lists.apache.org/thread.html/rca37935d661f4689cb4119f1b3b224413b22be161b678e6e6ce0c69b@%3Ccommits.nifi.apache.org%3E",
"https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html",
"https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html",
"https://lists.debian.org/debian-lts-announce/2020/02/msg00024.html",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/",
"https://nvd.nist.gov/vuln/detail/CVE-2019-11358",
"https://seclists.org/bugtraq/2019/Apr/32",
"https://seclists.org/bugtraq/2019/Jun/12",
"https://seclists.org/bugtraq/2019/May/18",
"https://security.netapp.com/advisory/ntap-20190919-0001/",
"https://snyk.io/vuln/SNYK-JS-JQUERY-174006",
"https://www.debian.org/security/2019/dsa-4434",
"https://www.debian.org/security/2019/dsa-4460",
"https://www.drupal.org/sa-core-2019-006",
"https://www.oracle.com//security-alerts/cpujul2021.html",
"https://www.oracle.com/security-alerts/cpuApr2021.html",
"https://www.oracle.com/security-alerts/cpuapr2020.html",
"https://www.oracle.com/security-alerts/cpujan2020.html",
"https://www.oracle.com/security-alerts/cpujan2021.html",
"https://www.oracle.com/security-alerts/cpujul2020.html",
"https://www.oracle.com/security-alerts/cpuoct2020.html",
"https://www.oracle.com/security-alerts/cpuoct2021.html",
"https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html",
"https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html",
"https://www.privacy-wise.com/mitigating-cve-2019-11358-in-old-versions-of-jquery/",
"https://www.synology.com/security/advisory/Synology_SA_19_19",
"https://www.tenable.com/security/tns-2019-08",
"https://www.tenable.com/security/tns-2020-02"
],
"PublishedDate": "2019-04-20T00:29:00Z",
"LastModifiedDate": "2021-10-20T11:15:00Z"
},
{
"VulnerabilityID": "CVE-2019-10744",
"PkgID": "lodash@4.17.4",
"PkgName": "lodash",
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.12",
"Layer": {},
"SeveritySource": "ghsa",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-10744",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Npm",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm"
},
"Title": "nodejs-lodash: prototype pollution in defaultsDeep function leading to modifying properties",
"Description": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.",
"Severity": "CRITICAL",
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:N/C:N/I:P/A:P",
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
"V2Score": 6.4,
"V3Score": 9.1
},
"redhat": {
"V3Vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H",
"V3Score": 9.1
}
},
"References": [
"https://access.redhat.com/errata/RHSA-2019:3024",
"https://access.redhat.com/security/cve/CVE-2019-10744",
"https://github.com/advisories/GHSA-jf85-cpcp-j695",
"https://github.com/lodash/lodash/pull/4336",
"https://nvd.nist.gov/vuln/detail/CVE-2019-10744",
"https://security.netapp.com/advisory/ntap-20191004-0005/",
"https://snyk.io/vuln/SNYK-JS-LODASH-450202",
"https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS",
"https://www.npmjs.com/advisories/1065",
"https://www.oracle.com/security-alerts/cpujan2021.html",
"https://www.oracle.com/security-alerts/cpuoct2020.html"
],
"PublishedDate": "2019-07-26T00:15:00Z",
"LastModifiedDate": "2021-03-16T13:57:00Z"
}
]
}
]
}

View File

@@ -26,7 +26,51 @@
"Title": "AWS Access Key ID", "Title": "AWS Access Key ID",
"StartLine": 3, "StartLine": 3,
"EndLine": 3, "EndLine": 3,
"Match": "export AWS_ACCESS_KEY_ID=*****" "Match": "export AWS_ACCESS_KEY_ID=********************",
"Code" : {
"Lines": [
{
"Number": 1,
"Content": "#!/bin/sh",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "#!/bin/sh",
"FirstCause": false,
"LastCause": false
},
{
"Number": 2,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "",
"FirstCause": false,
"LastCause": false
},
{
"Number": 3,
"Content": "export AWS_ACCESS_KEY_ID=********************",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "export AWS_ACCESS_KEY_ID=********************",
"FirstCause": true,
"LastCause": true
},
{
"Number": 4,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "",
"FirstCause": false,
"LastCause": false
}
]
}
}, },
{ {
"RuleID": "mysecret", "RuleID": "mysecret",
@@ -35,7 +79,41 @@
"Title": "My Secret", "Title": "My Secret",
"StartLine": 7, "StartLine": 7,
"EndLine": 7, "EndLine": 7,
"Match": "echo *****" "Match": "echo ********",
"Code" : {
"Lines": [
{
"Number": 5,
"Content": "export GITHUB_PAT=ghp_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "export GITHUB_PAT=ghp_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"FirstCause": false,
"LastCause": false
},
{
"Number": 6,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "",
"FirstCause": false,
"LastCause": false
},
{
"Number": 7,
"Content": "echo ********",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "echo ********",
"FirstCause": true,
"LastCause": true
}
]
}
} }
] ]
} }

View File

@@ -32,7 +32,10 @@ labels:
description: Categorizes issue or PR as related to a unit/integration test. description: Categorizes issue or PR as related to a unit/integration test.
- name: kind/security - name: kind/security
color: f4dddc color: f4dddc
description: security issues description: Categorizes issue or PR as related to Trivy's own security or internal vulnerabilities.
- name: kind/integration
color: f4dddc
description: Categorizes issue or PR as related to a third party integration of Trivy.
# lifecycle for the stale bot # lifecycle for the stale bot
- name: lifecycle/frozen - name: lifecycle/frozen
@@ -125,6 +128,3 @@ labels:
- name: help wanted - name: help wanted
color: 006b75 color: 006b75
description: Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. description: Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
- name: vulnerability
color: e11d21
description: Categorizes issue or PR as related to Trivy's own vulnerabilities.

View File

@@ -61,6 +61,8 @@ nav:
- Scanning: docs/secret/scanning.md - Scanning: docs/secret/scanning.md
- Configuration: docs/secret/configuration.md - Configuration: docs/secret/configuration.md
- Examples: docs/secret/examples.md - Examples: docs/secret/examples.md
- License:
- Scanning: docs/licenses/scanning.md
- Kubernetes: - Kubernetes:
- CLI: - CLI:
- Scanning: docs/kubernetes/cli/scanning.md - Scanning: docs/kubernetes/cli/scanning.md
@@ -70,6 +72,8 @@ nav:
- Overview: docs/sbom/index.md - Overview: docs/sbom/index.md
- CycloneDX: docs/sbom/cyclonedx.md - CycloneDX: docs/sbom/cyclonedx.md
- SPDX: docs/sbom/spdx.md - SPDX: docs/sbom/spdx.md
- Attestation:
- SBOM: docs/attestation/sbom.md
- Integrations: - Integrations:
- Overview: docs/integrations/index.md - Overview: docs/integrations/index.md
- GitHub Actions: docs/integrations/github-actions.md - GitHub Actions: docs/integrations/github-actions.md
@@ -97,6 +101,9 @@ nav:
- ACR (Azure Container Registry): docs/advanced/private-registries/acr.md - ACR (Azure Container Registry): docs/advanced/private-registries/acr.md
- Self-Hosted: docs/advanced/private-registries/self.md - Self-Hosted: docs/advanced/private-registries/self.md
- References: - References:
- Customization:
- Environment variables: docs/references/customization/envs.md
- Config file: docs/references/customization/config-file.md
- CLI: - CLI:
- Overview: docs/references/cli/index.md - Overview: docs/references/cli/index.md
- Image: docs/references/cli/image.md - Image: docs/references/cli/image.md

File diff suppressed because it is too large Load Diff

View File

@@ -70,37 +70,36 @@ Vulnerability DB:
name string name string
arguments []string // 1st argument is path to trivy binaries arguments []string // 1st argument is path to trivy binaries
want string want string
wantErr string
}{ }{
{ {
name: "happy path. '-v' flag is used", name: "happy path. '-v' flag is used",
arguments: []string{"trivy", "-v", "--cache-dir", "testdata"}, arguments: []string{"-v", "--cache-dir", "testdata"},
want: tableOutput, want: tableOutput,
}, },
{ {
name: "happy path. '-version' flag is used", name: "happy path. '-version' flag is used",
arguments: []string{"trivy", "-version", "--cache-dir", "testdata"}, arguments: []string{"--version", "--cache-dir", "testdata"},
want: tableOutput, want: tableOutput,
}, },
{ {
name: "happy path. 'version' command is used", name: "happy path. 'version' command is used",
arguments: []string{"trivy", "--cache-dir", "testdata", "version"}, arguments: []string{"--cache-dir", "testdata", "version"},
want: tableOutput, want: tableOutput,
}, },
{ {
name: "happy path. 'version', '--format json' flags are used", name: "happy path. 'version', '--format json' flags are used",
arguments: []string{"trivy", "--cache-dir", "testdata", "version", "--format", "json"}, arguments: []string{"--cache-dir", "testdata", "version", "--format", "json"},
want: jsonOutput, want: jsonOutput,
}, },
{ {
name: "sad path. '-v', '--format json' flags are used", name: "happy path. '-v', '--format json' flags are used",
arguments: []string{"trivy", "-v", "--format", "json"}, arguments: []string{"--cache-dir", "testdata", "-v", "--format", "json"},
wantErr: "flag provided but not defined: -format", want: jsonOutput,
}, },
{ {
name: "sad path. '-version', '--format json' flags are used", name: "happy path. '--version', '--format json' flags are used",
arguments: []string{"trivy", "-version", "--format", "json"}, arguments: []string{"--cache-dir", "testdata", "--version", "--format", "json"},
wantErr: "flag provided but not defined: -format", want: jsonOutput,
}, },
} }
@@ -108,24 +107,12 @@ Vulnerability DB:
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
got := new(bytes.Buffer) got := new(bytes.Buffer)
app := NewApp("test") app := NewApp("test")
app.Writer = got SetOut(got)
app.SetArgs(test.arguments)
err := app.Run(test.arguments) err := app.Execute()
if test.wantErr != "" { require.NoError(t, err)
require.Error(t, err)
assert.Contains(t, err.Error(), test.wantErr)
return
}
assert.Equal(t, test.want, got.String()) assert.Equal(t, test.want, got.String())
}) })
} }
} }
func TestNewCommands(t *testing.T) {
NewApp("test")
NewClientCommand()
NewFilesystemCommand()
NewImageCommand()
NewRepositoryCommand()
NewServerCommand()
}

View File

@@ -1,27 +0,0 @@
package artifact
import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/types"
)
// ConfigRun runs scan on config files
func ConfigRun(ctx *cli.Context) error {
opt, err := InitOption(ctx)
if err != nil {
return xerrors.Errorf("option error: %w", err)
}
// Disable OS and language analyzers
opt.DisabledAnalyzers = append(analyzer.TypeOSes, analyzer.TypeLanguages...)
// Scan only config files
opt.VulnType = nil
opt.SecurityChecks = []string{types.SecurityCheckConfig}
// Run filesystem command internally
return run(ctx.Context, opt, filesystemArtifact)
}

View File

@@ -1,38 +0,0 @@
package artifact
import (
"context"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/scanner"
)
// filesystemStandaloneScanner initializes a filesystem scanner in standalone mode
func filesystemStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeFilesystemScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// filesystemRemoteScanner initializes a filesystem scanner in client/server mode
func filesystemRemoteScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeRemoteFilesystemScanner(ctx, conf.Target, conf.ArtifactCache, conf.RemoteOption, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// FilesystemRun runs scan on filesystem for language-specific dependencies and config files
func FilesystemRun(ctx *cli.Context) error {
return Run(ctx, filesystemArtifact)
}
// RootfsRun runs scan on rootfs.
func RootfsRun(ctx *cli.Context) error {
return Run(ctx, rootfsArtifact)
}

View File

@@ -49,6 +49,12 @@ func initializeRepositoryScanner(ctx context.Context, url string, artifactCache
return scanner.Scanner{}, nil, nil return scanner.Scanner{}, nil, nil
} }
func initializeSBOMScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache,
localArtifactCache cache.LocalArtifactCache, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
wire.Build(scanner.StandaloneSBOMSet)
return scanner.Scanner{}, nil, nil
}
///////////////// /////////////////
// Client/Server // Client/Server
///////////////// /////////////////
@@ -76,3 +82,10 @@ func initializeRemoteFilesystemScanner(ctx context.Context, path string, artifac
wire.Build(scanner.RemoteFilesystemSet) wire.Build(scanner.RemoteFilesystemSet)
return scanner.Scanner{}, nil, nil return scanner.Scanner{}, nil, nil
} }
// initializeRemoteSBOMScanner is for sbom scanning in client/server mode
func initializeRemoteSBOMScanner(ctx context.Context, path string, artifactCache cache.ArtifactCache,
remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
wire.Build(scanner.RemoteSBOMSet)
return scanner.Scanner{}, nil, nil
}

View File

@@ -1,93 +0,0 @@
package artifact
import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
)
// Option holds the artifact options
type Option struct {
option.GlobalOption
option.ArtifactOption
option.DBOption
option.ImageOption
option.ReportOption
option.CacheOption
option.ConfigOption
option.RemoteOption
option.SbomOption
option.SecretOption
option.KubernetesOption
option.OtherOption
// 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
func NewOption(c *cli.Context) (Option, error) {
gc, err := option.NewGlobalOption(c)
if err != nil {
return Option{}, xerrors.Errorf("failed to initialize global options: %w", err)
}
return Option{
GlobalOption: gc,
ArtifactOption: option.NewArtifactOption(c),
DBOption: option.NewDBOption(c),
ImageOption: option.NewImageOption(c),
ReportOption: option.NewReportOption(c),
CacheOption: option.NewCacheOption(c),
ConfigOption: option.NewConfigOption(c),
RemoteOption: option.NewRemoteOption(c),
SbomOption: option.NewSbomOption(c),
SecretOption: option.NewSecretOption(c),
KubernetesOption: option.NewKubernetesOption(c),
OtherOption: option.NewOtherOption(c),
}, nil
}
// Init initializes the artifact options
func (c *Option) Init() error {
if err := c.initPreScanOptions(); err != nil {
return err
}
// --clear-cache, --download-db-only and --reset don't conduct the scan
if c.skipScan() {
return nil
}
if err := c.ArtifactOption.Init(c.Context, c.Logger); err != nil {
return err
}
return nil
}
func (c *Option) initPreScanOptions() error {
if err := c.ReportOption.Init(c.Context.App.Writer, c.Logger); err != nil {
return err
}
if err := c.DBOption.Init(); err != nil {
return err
}
if err := c.CacheOption.Init(); err != nil {
return err
}
if err := c.SbomOption.Init(c.Context, c.Logger); err != nil {
return err
}
c.RemoteOption.Init(c.Logger)
return nil
}
func (c *Option) skipScan() bool {
if c.ClearCache || c.DownloadDBOnly || c.Reset {
return true
}
return false
}

View File

@@ -1,334 +0,0 @@
package artifact
import (
"flag"
"net/http"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/aquasecurity/trivy/pkg/report"
"github.com/aquasecurity/trivy/pkg/types"
)
func TestOption_Init(t *testing.T) {
tests := []struct {
name string
args []string
logs []string
want Option
wantErr string
}{
{
name: "happy path",
args: []string{"--severity", "CRITICAL", "--vuln-type", "os", "--quiet", "alpine:3.10"},
want: Option{
GlobalOption: option.GlobalOption{
Quiet: true,
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.10",
},
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
VulnType: []string{types.VulnTypeOS},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Output: os.Stdout,
},
},
},
{
name: "config scanning",
args: []string{"--severity", "CRITICAL", "--security-checks", "config", "--quiet", "alpine:3.10"},
want: Option{
GlobalOption: option.GlobalOption{
Quiet: true,
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.10",
},
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckConfig},
Output: os.Stdout,
},
},
},
{
name: "happy path with token and token header",
args: []string{"--server", "http://localhost:8080", "--token", "secret", "--token-header", "X-Trivy-Token", "alpine:3.11"},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.11",
},
RemoteOption: option.RemoteOption{
RemoteAddr: "http://localhost:8080",
CustomHeaders: http.Header{
"X-Trivy-Token": []string{"secret"},
},
},
},
},
{
name: "invalid option combination: token and token header without server",
args: []string{"--token", "secret", "--token-header", "X-Trivy-Token", "alpine:3.11"},
logs: []string{
`"--token" can be used only with "--server"`,
},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.11",
},
},
},
{
name: "happy path with good custom headers",
args: []string{"--server", "http://localhost:8080", "--custom-headers", "foo:bar", "alpine:3.11"},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.11",
},
RemoteOption: option.RemoteOption{
RemoteAddr: "http://localhost:8080",
CustomHeaders: http.Header{
"Foo": []string{"bar"},
}},
},
},
{
name: "happy path with bad custom headers",
args: []string{"--server", "http://localhost:8080", "--custom-headers", "foobaz", "alpine:3.11"},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.11",
},
RemoteOption: option.RemoteOption{RemoteAddr: "http://localhost:8080", CustomHeaders: http.Header{}},
},
},
{
name: "happy path: reset",
args: []string{"--reset"},
want: Option{
DBOption: option.DBOption{
Reset: true,
},
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
},
},
{
name: "happy path with an unknown severity",
args: []string{"--severity", "CRITICAL,INVALID", "centos:7"},
logs: []string{
"unknown severity option: unknown severity: INVALID",
},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityUnknown},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
},
ArtifactOption: option.ArtifactOption{
Target: "centos:7",
},
},
},
{
name: "invalid option combination: --template enabled without --format",
args: []string{"--template", "@contrib/gitlab.tpl", "gitlab/gitlab-ce:12.7.2-ce.0"},
logs: []string{
"'--template' is ignored because '--format template' is not specified. Use '--template' option with '--format template' option.",
},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Template: "@contrib/gitlab.tpl",
},
ArtifactOption: option.ArtifactOption{
Target: "gitlab/gitlab-ce:12.7.2-ce.0",
},
},
},
{
name: "invalid option combination: --template and --format json",
args: []string{"--format", "json", "--template", "@contrib/gitlab.tpl", "gitlab/gitlab-ce:12.7.2-ce.0"},
logs: []string{
"'--template' is ignored because '--format json' is specified. Use '--template' option with '--format template' option.",
},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Template: "@contrib/gitlab.tpl",
Format: "json",
},
ArtifactOption: option.ArtifactOption{
Target: "gitlab/gitlab-ce:12.7.2-ce.0",
},
},
},
{
name: "json and list all packages",
args: []string{"--format", "json", "--list-all-pkgs", "gitlab/gitlab-ce:12.7.2-ce.0"},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Format: "json",
ListAllPkgs: true,
},
ArtifactOption: option.ArtifactOption{
Target: "gitlab/gitlab-ce:12.7.2-ce.0",
},
},
},
{
name: "invalid option combination: --format template without --template",
args: []string{"--format", "template", "--severity", "MEDIUM", "gitlab/gitlab-ce:12.7.2-ce.0"},
logs: []string{
"'--format template' is ignored because '--template' is not specified. Specify '--template' option when you use '--format template'.",
},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityMedium},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Format: "template",
},
ArtifactOption: option.ArtifactOption{
Target: "gitlab/gitlab-ce:12.7.2-ce.0",
},
},
},
{
name: "github enables list-all-pkgs",
args: []string{"--format", "github", "alpine:3.15"},
want: Option{
ReportOption: option.ReportOption{
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
Output: os.Stdout,
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
SecurityChecks: []string{types.SecurityCheckVulnerability},
Format: report.FormatGitHub,
ListAllPkgs: true,
},
ArtifactOption: option.ArtifactOption{
Target: "alpine:3.15",
},
},
},
{
name: "sad: skip and download db",
args: []string{"--skip-db-update", "--download-db-only", "alpine:3.10"},
wantErr: "--skip-db-update and --download-db-only options can not be specified both",
},
{
name: "sad: multiple image names",
args: []string{"centos:7", "alpine:3.10"},
logs: []string{
"multiple targets cannot be specified",
},
wantErr: "arguments error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core, obs := observer.New(zap.InfoLevel)
logger := zap.New(core)
app := cli.NewApp()
set := flag.NewFlagSet("test", 0)
set.Bool("quiet", false, "")
set.Bool("no-progress", false, "")
set.Bool("reset", false, "")
set.Bool("skip-db-update", false, "")
set.Bool("download-db-only", false, "")
set.Bool("list-all-pkgs", false, "")
set.String("severity", "CRITICAL", "")
set.String("vuln-type", "os,library", "")
set.String("security-checks", "vuln", "")
set.String("template", "", "")
set.String("format", "", "")
set.String("server", "", "")
set.String("token", "", "")
set.String("token-header", option.DefaultTokenHeader, "")
set.Var(&cli.StringSlice{}, "custom-headers", "")
ctx := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
c, err := NewOption(ctx)
require.NoError(t, err, err)
c.GlobalOption.Logger = logger.Sugar()
err = c.Init()
// tests log messages
var gotMessages []string
for _, entry := range obs.AllUntimed() {
gotMessages = append(gotMessages, entry.Message)
}
assert.Equal(t, tt.logs, gotMessages, tt.name)
// test the error
switch {
case tt.wantErr != "":
require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
return
default:
assert.NoError(t, err, tt.name)
}
tt.want.GlobalOption.Context = ctx
tt.want.GlobalOption.Logger = logger.Sugar()
assert.Equal(t, tt.want, c, tt.name)
})
}
}

View File

@@ -1,24 +0,0 @@
package artifact
import (
"context"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/scanner"
)
// filesystemStandaloneScanner initializes a repository scanner in standalone mode
func repositoryStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeRepositoryScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// RepositoryRun runs scan on repository
func RepositoryRun(ctx *cli.Context) error {
return Run(ctx, repositoryArtifact)
}

View File

@@ -3,11 +3,10 @@ package artifact
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"os" "os"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/urfave/cli/v2" "github.com/spf13/viper"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@@ -19,6 +18,7 @@ import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/secret" "github.com/aquasecurity/trivy/pkg/fanal/analyzer/secret"
"github.com/aquasecurity/trivy/pkg/fanal/artifact" "github.com/aquasecurity/trivy/pkg/fanal/artifact"
"github.com/aquasecurity/trivy/pkg/fanal/cache" "github.com/aquasecurity/trivy/pkg/fanal/cache"
"github.com/aquasecurity/trivy/pkg/flag"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/module" "github.com/aquasecurity/trivy/pkg/module"
pkgReport "github.com/aquasecurity/trivy/pkg/report" pkgReport "github.com/aquasecurity/trivy/pkg/report"
@@ -29,23 +29,21 @@ import (
"github.com/aquasecurity/trivy/pkg/utils" "github.com/aquasecurity/trivy/pkg/utils"
) )
type ArtifactType string // TargetKind represents what kind of artifact Trivy scans
type TargetKind string
const ( const (
containerImageArtifact ArtifactType = "image" TargetContainerImage TargetKind = "image"
filesystemArtifact ArtifactType = "fs" TargetFilesystem TargetKind = "fs"
rootfsArtifact ArtifactType = "rootfs" TargetRootfs TargetKind = "rootfs"
repositoryArtifact ArtifactType = "repo" TargetRepository TargetKind = "repo"
imageArchiveArtifact ArtifactType = "archive" TargetImageArchive TargetKind = "archive"
TargetSBOM TargetKind = "sbom"
) )
var ( var (
defaultPolicyNamespaces = []string{"appshield", "defsec", "builtin"} defaultPolicyNamespaces = []string{"appshield", "defsec", "builtin"}
SkipScan = errors.New("skip subsequent processes")
supportedArtifactTypes = []ArtifactType{containerImageArtifact, filesystemArtifact, rootfsArtifact,
repositoryArtifact, imageArchiveArtifact}
SkipScan = errors.New("skip subsequent processes")
) )
// InitializeScanner defines the initialize function signature of scanner // InitializeScanner defines the initialize function signature of scanner
@@ -68,17 +66,19 @@ type ScannerConfig struct {
type Runner interface { type Runner interface {
// ScanImage scans an image // ScanImage scans an image
ScanImage(ctx context.Context, opt Option) (types.Report, error) ScanImage(ctx context.Context, opts flag.Options) (types.Report, error)
// ScanFilesystem scans a filesystem // ScanFilesystem scans a filesystem
ScanFilesystem(ctx context.Context, opt Option) (types.Report, error) ScanFilesystem(ctx context.Context, opts flag.Options) (types.Report, error)
// ScanRootfs scans rootfs // ScanRootfs scans rootfs
ScanRootfs(ctx context.Context, opt Option) (types.Report, error) ScanRootfs(ctx context.Context, opts flag.Options) (types.Report, error)
// ScanRepository scans repository // ScanRepository scans repository
ScanRepository(ctx context.Context, opt Option) (types.Report, error) ScanRepository(ctx context.Context, opts flag.Options) (types.Report, error)
// ScanSBOM scans SBOM
ScanSBOM(ctx context.Context, opts flag.Options) (types.Report, error)
// Filter filter a report // Filter filter a report
Filter(ctx context.Context, opt Option, report types.Report) (types.Report, error) Filter(ctx context.Context, opts flag.Options, report types.Report) (types.Report, error)
// Report a writes a report // Report a writes a report
Report(opt Option, report types.Report) error Report(opts flag.Options, report types.Report) error
// Close closes runner // Close closes runner
Close(ctx context.Context) error Close(ctx context.Context) error
} }
@@ -94,6 +94,7 @@ type runner struct {
type runnerOption func(*runner) type runnerOption func(*runner)
// WithCacheClient takes a custom cache implementation // WithCacheClient takes a custom cache implementation
// It is useful when Trivy is imported as a library.
func WithCacheClient(c cache.Cache) runnerOption { func WithCacheClient(c cache.Cache) runnerOption {
return func(r *runner) { return func(r *runner) {
r.cache = c r.cache = c
@@ -102,27 +103,23 @@ func WithCacheClient(c cache.Cache) runnerOption {
// NewRunner initializes Runner that provides scanning functionalities. // NewRunner initializes Runner that provides scanning functionalities.
// It is possible to return SkipScan and it must be handled by caller. // It is possible to return SkipScan and it must be handled by caller.
func NewRunner(cliOption Option, opts ...runnerOption) (Runner, error) { func NewRunner(ctx context.Context, cliOptions flag.Options, opts ...runnerOption) (Runner, error) {
r := &runner{} r := &runner{}
for _, opt := range opts { for _, opt := range opts {
opt(r) opt(r)
} }
err := log.InitLogger(cliOption.Debug, cliOption.Quiet) if err := r.initCache(cliOptions); err != nil {
if err != nil {
return nil, xerrors.Errorf("logger error: %w", err)
}
if err = r.initCache(cliOption); err != nil {
return nil, xerrors.Errorf("cache error: %w", err) return nil, xerrors.Errorf("cache error: %w", err)
} }
if err = r.initDB(cliOption); err != nil { // Update the vulnerability database if needed.
if err := r.initDB(cliOptions); err != nil {
return nil, xerrors.Errorf("DB error: %w", err) return nil, xerrors.Errorf("DB error: %w", err)
} }
// Initialize WASM modules // Initialize WASM modules
m, err := module.NewManager(cliOption.Context.Context) m, err := module.NewManager(ctx)
if err != nil { if err != nil {
return nil, xerrors.Errorf("WASM module error: %w", err) return nil, xerrors.Errorf("WASM module error: %w", err)
} }
@@ -151,46 +148,46 @@ func (r *runner) Close(ctx context.Context) error {
return errs return errs
} }
func (r *runner) ScanImage(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanImage(ctx context.Context, opts flag.Options) (types.Report, error) {
// Disable the lock file scanning // Disable the lock file scanning
opt.DisabledAnalyzers = analyzer.TypeLockfiles opts.DisabledAnalyzers = analyzer.TypeLockfiles
var s InitializeScanner var s InitializeScanner
switch { switch {
case opt.Input != "" && opt.RemoteAddr == "": case opts.Input != "" && opts.ServerAddr == "":
// Scan image tarball in standalone mode // Scan image tarball in standalone mode
s = archiveStandaloneScanner s = archiveStandaloneScanner
case opt.Input != "" && opt.RemoteAddr != "": case opts.Input != "" && opts.ServerAddr != "":
// Scan image tarball in client/server mode // Scan image tarball in client/server mode
s = archiveRemoteScanner s = archiveRemoteScanner
case opt.Input == "" && opt.RemoteAddr == "": case opts.Input == "" && opts.ServerAddr == "":
// Scan container image in standalone mode // Scan container image in standalone mode
s = imageStandaloneScanner s = imageStandaloneScanner
case opt.Input == "" && opt.RemoteAddr != "": case opts.Input == "" && opts.ServerAddr != "":
// Scan container image in client/server mode // Scan container image in client/server mode
s = imageRemoteScanner s = imageRemoteScanner
} }
return r.scanArtifact(ctx, opt, s) return r.scanArtifact(ctx, opts, s)
} }
func (r *runner) ScanFilesystem(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanFilesystem(ctx context.Context, opts flag.Options) (types.Report, error) {
// Disable the individual package scanning // Disable the individual package scanning
opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeIndividualPkgs...) opts.DisabledAnalyzers = append(opts.DisabledAnalyzers, analyzer.TypeIndividualPkgs...)
return r.scanFS(ctx, opt) return r.scanFS(ctx, opts)
} }
func (r *runner) ScanRootfs(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanRootfs(ctx context.Context, opts flag.Options) (types.Report, error) {
// Disable the lock file scanning // Disable the lock file scanning
opt.DisabledAnalyzers = append(opt.DisabledAnalyzers, analyzer.TypeLockfiles...) opts.DisabledAnalyzers = append(opts.DisabledAnalyzers, analyzer.TypeLockfiles...)
return r.scanFS(ctx, opt) return r.scanFS(ctx, opts)
} }
func (r *runner) scanFS(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) scanFS(ctx context.Context, opts flag.Options) (types.Report, error) {
var s InitializeScanner var s InitializeScanner
if opt.RemoteAddr == "" { if opts.ServerAddr == "" {
// Scan filesystem in standalone mode // Scan filesystem in standalone mode
s = filesystemStandaloneScanner s = filesystemStandaloneScanner
} else { } else {
@@ -198,21 +195,34 @@ func (r *runner) scanFS(ctx context.Context, opt Option) (types.Report, error) {
s = filesystemRemoteScanner s = filesystemRemoteScanner
} }
return r.scanArtifact(ctx, opt, s) return r.scanArtifact(ctx, opts, s)
} }
func (r *runner) ScanRepository(ctx context.Context, opt Option) (types.Report, error) { func (r *runner) ScanRepository(ctx context.Context, opts flag.Options) (types.Report, error) {
// Do not scan OS packages // Do not scan OS packages
opt.VulnType = []string{types.VulnTypeLibrary} opts.VulnType = []string{types.VulnTypeLibrary}
// Disable the OS analyzers and individual package analyzers // Disable the OS analyzers and individual package analyzers
opt.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...) opts.DisabledAnalyzers = append(analyzer.TypeIndividualPkgs, analyzer.TypeOSes...)
return r.scanArtifact(ctx, opt, repositoryStandaloneScanner) return r.scanArtifact(ctx, opts, repositoryStandaloneScanner)
} }
func (r *runner) scanArtifact(ctx context.Context, opt Option, initializeScanner InitializeScanner) (types.Report, error) { func (r *runner) ScanSBOM(ctx context.Context, opts flag.Options) (types.Report, error) {
report, err := scan(ctx, opt, initializeScanner, r.cache) var s InitializeScanner
if opts.ServerAddr == "" {
// Scan cycloneDX in standalone mode
s = sbomStandaloneScanner
} else {
// Scan cycloneDX in client/server mode
s = sbomRemoteScanner
}
return r.scanArtifact(ctx, opts, s)
}
func (r *runner) scanArtifact(ctx context.Context, opts flag.Options, initializeScanner InitializeScanner) (types.Report, error) {
report, err := scan(ctx, opts, initializeScanner, r.cache)
if err != nil { if err != nil {
return types.Report{}, xerrors.Errorf("scan error: %w", err) return types.Report{}, xerrors.Errorf("scan error: %w", err)
} }
@@ -220,34 +230,30 @@ func (r *runner) scanArtifact(ctx context.Context, opt Option, initializeScanner
return report, nil return report, nil
} }
func (r *runner) Filter(ctx context.Context, opt Option, report types.Report) (types.Report, error) { func (r *runner) Filter(ctx context.Context, opts flag.Options, report types.Report) (types.Report, error) {
results := report.Results results := report.Results
// Filter results // Filter results
for i := range results { for i := range results {
vulns, misconfSummary, misconfs, secrets, err := result.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations, results[i].Secrets, err := result.Filter(ctx, &results[i], opts.Severities, opts.IgnoreUnfixed, opts.IncludeNonFailures,
opt.Severities, opt.IgnoreUnfixed, opt.IncludeNonFailures, opt.IgnoreFile, opt.IgnorePolicy) opts.IgnoreFile, opts.IgnorePolicy, opts.IgnoredLicenses)
if err != nil { if err != nil {
return types.Report{}, xerrors.Errorf("unable to filter vulnerabilities: %w", err) return types.Report{}, xerrors.Errorf("unable to filter vulnerabilities: %w", err)
} }
results[i].Vulnerabilities = vulns
results[i].Misconfigurations = misconfs
results[i].MisconfSummary = misconfSummary
results[i].Secrets = secrets
} }
return report, nil return report, nil
} }
func (r *runner) Report(opt Option, report types.Report) error { func (r *runner) Report(opts flag.Options, report types.Report) error {
if err := pkgReport.Write(report, pkgReport.Option{ if err := pkgReport.Write(report, pkgReport.Option{
AppVersion: opt.GlobalOption.AppVersion, AppVersion: opts.AppVersion,
Format: opt.Format, Format: opts.Format,
Output: opt.Output, Output: opts.Output,
Tree: opt.DependencyTree, Tree: opts.DependencyTree,
Severities: opt.Severities, Severities: opts.Severities,
OutputTemplate: opt.Template, OutputTemplate: opts.Template,
IncludeNonFailures: opt.IncludeNonFailures, IncludeNonFailures: opts.IncludeNonFailures,
Trace: opt.Trace, Trace: opts.Trace,
}); err != nil { }); err != nil {
return xerrors.Errorf("unable to write results: %w", err) return xerrors.Errorf("unable to write results: %w", err)
} }
@@ -255,23 +261,23 @@ func (r *runner) Report(opt Option, report types.Report) error {
return nil return nil
} }
func (r *runner) initDB(c Option) 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 c.RemoteAddr != "" || !slices.Contains(c.SecurityChecks, types.SecurityCheckVulnerability) { if opts.ServerAddr != "" || !slices.Contains(opts.SecurityChecks, types.SecurityCheckVulnerability) {
return nil return nil
} }
// download the database file // download the database file
noProgress := c.Quiet || c.NoProgress noProgress := opts.Quiet || opts.NoProgress
if err := operation.DownloadDB(c.AppVersion, c.CacheDir, c.DBRepository, noProgress, c.Insecure, c.SkipDBUpdate); err != nil { if err := operation.DownloadDB(opts.AppVersion, opts.CacheDir, opts.DBRepository, noProgress, opts.Insecure, opts.SkipDBUpdate); err != nil {
return err return err
} }
if c.DownloadDBOnly { if opts.DownloadDBOnly {
return SkipScan return SkipScan
} }
if err := db.Init(c.CacheDir); err != nil { if err := db.Init(opts.CacheDir); err != nil {
return xerrors.Errorf("error in vulnerability DB initialize: %w", err) return xerrors.Errorf("error in vulnerability DB initialize: %w", err)
} }
r.dbOpen = true r.dbOpen = true
@@ -279,58 +285,59 @@ func (r *runner) initDB(c Option) error {
return nil return nil
} }
func (r *runner) initCache(c Option) error { func (r *runner) initCache(opts flag.Options) error {
// Skip initializing cache when custom cache is passed // Skip initializing cache when custom cache is passed
if r.cache != nil { if r.cache != nil {
return nil return nil
} }
// client/server mode // client/server mode
if c.RemoteAddr != "" { if opts.ServerAddr != "" {
remoteCache := tcache.NewRemoteCache(c.RemoteAddr, c.CustomHeaders, c.Insecure) remoteCache := tcache.NewRemoteCache(opts.ServerAddr, opts.CustomHeaders, opts.Insecure)
r.cache = tcache.NopCache(remoteCache) r.cache = tcache.NopCache(remoteCache)
return nil return nil
} }
// standalone mode // standalone mode
utils.SetCacheDir(c.CacheDir) utils.SetCacheDir(opts.CacheDir)
cache, err := operation.NewCache(c.CacheOption) cacheClient, err := operation.NewCache(opts.CacheOptions)
if err != nil { if err != nil {
return xerrors.Errorf("unable to initialize the cache: %w", err) return xerrors.Errorf("unable to initialize the cache: %w", err)
} }
log.Logger.Debugf("cache dir: %s", utils.CacheDir()) log.Logger.Debugf("cache dir: %s", utils.CacheDir())
if c.Reset { if opts.Reset {
defer cache.Close() defer cacheClient.Close()
if err = cache.Reset(); err != nil { if err = cacheClient.Reset(); err != nil {
return xerrors.Errorf("cache reset error: %w", err) return xerrors.Errorf("cache reset error: %w", err)
} }
return SkipScan return SkipScan
} }
if c.ClearCache { if opts.ClearCache {
defer cache.Close() defer cacheClient.Close()
if err = cache.ClearArtifacts(); err != nil { if err = cacheClient.ClearArtifacts(); err != nil {
return xerrors.Errorf("cache clear error: %w", err) return xerrors.Errorf("cache clear error: %w", err)
} }
return SkipScan return SkipScan
} }
r.cache = cache r.cache = cacheClient
return nil return nil
} }
// Run performs artifact scanning // Run performs artifact scanning
func Run(cliCtx *cli.Context, artifactType ArtifactType) error { //func Run(cliCtx *cli.Context, targetKind TargetKind) error {
opt, err := InitOption(cliCtx) // opt, err := InitOption(cliCtx)
if err != nil { // if err != nil {
return err // return xerrors.Errorf("InitOption: %w", err)
} // }
//
// return run(cliCtx.Context, opt, targetKind)
//}
return run(cliCtx.Context, opt, artifactType) // Run performs artifact scanning
} func Run(ctx context.Context, opts flag.Options, targetKind TargetKind) (err error) {
ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
func run(ctx context.Context, opt Option, artifactType ArtifactType) (err error) {
ctx, cancel := context.WithTimeout(ctx, opt.Timeout)
defer cancel() defer cancel()
defer func() { defer func() {
@@ -339,7 +346,12 @@ func run(ctx context.Context, opt Option, artifactType ArtifactType) (err error)
} }
}() }()
r, err := NewRunner(opt) if opts.GenerateDefaultConfig {
log.Logger.Info("Writing the default config to trivy-default.yaml...")
return viper.SafeWriteConfigAs("trivy-default.yaml")
}
r, err := NewRunner(ctx, opts)
if err != nil { if err != nil {
if errors.Is(err, SkipScan) { if errors.Is(err, SkipScan) {
return nil return nil
@@ -349,123 +361,124 @@ func run(ctx context.Context, opt Option, artifactType ArtifactType) (err error)
defer r.Close(ctx) defer r.Close(ctx)
var report types.Report var report types.Report
switch artifactType { switch targetKind {
case containerImageArtifact, imageArchiveArtifact: case TargetContainerImage, TargetImageArchive:
if report, err = r.ScanImage(ctx, opt); err != nil { if report, err = r.ScanImage(ctx, opts); err != nil {
return xerrors.Errorf("image scan error: %w", err) return xerrors.Errorf("image scan error: %w", err)
} }
case filesystemArtifact: case TargetFilesystem:
if report, err = r.ScanFilesystem(ctx, opt); err != nil { if report, err = r.ScanFilesystem(ctx, opts); err != nil {
return xerrors.Errorf("filesystem scan error: %w", err) return xerrors.Errorf("filesystem scan error: %w", err)
} }
case rootfsArtifact: case TargetRootfs:
if report, err = r.ScanRootfs(ctx, opt); err != nil { if report, err = r.ScanRootfs(ctx, opts); err != nil {
return xerrors.Errorf("rootfs scan error: %w", err) return xerrors.Errorf("rootfs scan error: %w", err)
} }
case repositoryArtifact: case TargetRepository:
if report, err = r.ScanRepository(ctx, opt); err != nil { if report, err = r.ScanRepository(ctx, opts); err != nil {
return xerrors.Errorf("repository scan error: %w", err) return xerrors.Errorf("repository scan error: %w", err)
} }
case TargetSBOM:
if report, err = r.ScanSBOM(ctx, opts); err != nil {
return xerrors.Errorf("sbom scan error: %w", err)
}
} }
report, err = r.Filter(ctx, opt, report) report, err = r.Filter(ctx, opts, report)
if err != nil { if err != nil {
return xerrors.Errorf("filter error: %w", err) return xerrors.Errorf("filter error: %w", err)
} }
if err = r.Report(opt, report); err != nil { if err = r.Report(opts, report); err != nil {
return xerrors.Errorf("report error: %w", err) return xerrors.Errorf("report error: %w", err)
} }
Exit(opt, report.Results.Failed()) Exit(opts, report.Results.Failed())
return nil return nil
} }
func InitOption(ctx *cli.Context) (Option, error) { func disabledAnalyzers(opts flag.Options) []analyzer.Type {
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 // Specified analyzers to be disabled depending on scanning modes
// e.g. The 'image' subcommand should disable the lock file scanning. // e.g. The 'image' subcommand should disable the lock file scanning.
analyzers := opt.DisabledAnalyzers analyzers := opts.DisabledAnalyzers
// It doesn't analyze apk commands by default. // It doesn't analyze apk commands by default.
if !opt.ScanRemovedPkgs { if !opts.ScanRemovedPkgs {
analyzers = append(analyzers, analyzer.TypeApkCommand) analyzers = append(analyzers, analyzer.TypeApkCommand)
} }
// Do not analyze programming language packages when not running in 'library' mode // Do not analyze programming language packages when not running in 'library'
if !slices.Contains(opt.VulnType, types.VulnTypeLibrary) { if !slices.Contains(opts.VulnType, types.VulnTypeLibrary) {
analyzers = append(analyzers, analyzer.TypeLanguages...) analyzers = append(analyzers, analyzer.TypeLanguages...)
} }
// Do not perform secret scanning when it is not specified. // Do not perform secret scanning when it is not specified.
if !slices.Contains(opt.SecurityChecks, types.SecurityCheckSecret) { if !slices.Contains(opts.SecurityChecks, types.SecurityCheckSecret) {
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(opt.SecurityChecks, types.SecurityCheckConfig) { if !slices.Contains(opts.SecurityChecks, types.SecurityCheckConfig) {
analyzers = append(analyzers, analyzer.TypeConfigFiles...) analyzers = append(analyzers, analyzer.TypeConfigFiles...)
} }
// Scanning file headers and license files is expensive.
// It is performed only when '--security-checks license' and '--license-full' are specified.
if !slices.Contains(opts.SecurityChecks, types.SecurityCheckLicense) || !opts.LicenseFull {
analyzers = append(analyzers, analyzer.TypeLicenseFile)
}
return analyzers return analyzers
} }
func initScannerConfig(opt Option, cacheClient cache.Cache) (ScannerConfig, types.ScanOptions, error) { func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfig, types.ScanOptions, error) {
target := opt.Target target := opts.Target
if opt.Input != "" { if opts.Input != "" {
target = opt.Input target = opts.Input
} }
scanOptions := types.ScanOptions{ scanOptions := types.ScanOptions{
VulnType: opt.VulnType, VulnType: opts.VulnType,
SecurityChecks: opt.SecurityChecks, SecurityChecks: opts.SecurityChecks,
ScanRemovedPackages: opt.ScanRemovedPkgs, // this is valid only for 'image' subcommand ScanRemovedPackages: opts.ScanRemovedPkgs, // this is valid only for 'image' subcommand
ListAllPackages: opt.ListAllPkgs, ListAllPackages: opts.ListAllPkgs,
LicenseCategories: opts.LicenseCategories,
} }
if slices.Contains(opt.SecurityChecks, types.SecurityCheckVulnerability) { if slices.Contains(opts.SecurityChecks, types.SecurityCheckVulnerability) {
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)
} }
// 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(opt.SecurityChecks, types.SecurityCheckConfig) { if slices.Contains(opts.SecurityChecks, types.SecurityCheckConfig) {
log.Logger.Info("Misconfiguration scanning is enabled") log.Logger.Info("Misconfiguration scanning is enabled")
configScannerOptions = config.ScannerOption{ configScannerOptions = config.ScannerOption{
Trace: opt.Trace, Trace: opts.Trace,
Namespaces: append(opt.PolicyNamespaces, defaultPolicyNamespaces...), Namespaces: append(opts.PolicyNamespaces, defaultPolicyNamespaces...),
PolicyPaths: opt.PolicyPaths, PolicyPaths: opts.PolicyPaths,
DataPaths: opt.DataPaths, DataPaths: opts.DataPaths,
FilePatterns: opt.FilePatterns, FilePatterns: opts.FilePatterns,
} }
} }
// Do not load config file for secret scanning // Do not load config file for secret scanning
if slices.Contains(opt.SecurityChecks, types.SecurityCheckSecret) { if slices.Contains(opts.SecurityChecks, types.SecurityCheckSecret) {
ver := fmt.Sprintf("v%s", opt.AppVersion)
if opt.AppVersion == "dev" {
ver = opt.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 '--security-checks 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", opts.AppVersion)
} else { } else {
opt.SecretConfigPath = "" opts.SecretConfigPath = ""
}
if slices.Contains(opts.SecurityChecks, types.SecurityCheckLicense) {
if opts.LicenseFull {
log.Logger.Info("Full license scanning is enabled")
} else {
log.Logger.Info("License scanning is enabled")
}
} }
return ScannerConfig{ return ScannerConfig{
@@ -473,33 +486,36 @@ func initScannerConfig(opt Option, cacheClient cache.Cache) (ScannerConfig, type
ArtifactCache: cacheClient, ArtifactCache: cacheClient,
LocalArtifactCache: cacheClient, LocalArtifactCache: cacheClient,
RemoteOption: client.ScannerOption{ RemoteOption: client.ScannerOption{
RemoteURL: opt.RemoteAddr, RemoteURL: opts.ServerAddr,
CustomHeaders: opt.CustomHeaders, CustomHeaders: opts.CustomHeaders,
Insecure: opt.Insecure, Insecure: opts.Insecure,
}, },
ArtifactOption: artifact.Option{ ArtifactOption: artifact.Option{
DisabledAnalyzers: disabledAnalyzers(opt), DisabledAnalyzers: disabledAnalyzers(opts),
SkipFiles: opt.SkipFiles, SkipFiles: opts.SkipFiles,
SkipDirs: opt.SkipDirs, SkipDirs: opts.SkipDirs,
InsecureSkipTLS: opt.Insecure, InsecureSkipTLS: opts.Insecure,
Offline: opt.OfflineScan, Offline: opts.OfflineScan,
NoProgress: opt.NoProgress || opt.Quiet, NoProgress: opts.NoProgress || opts.Quiet,
RepoBranch: opts.RepoBranch,
RepoCommit: opts.RepoCommit,
RepoTag: opts.RepoTag,
// For misconfiguration scanning // For misconfiguration scanning
MisconfScannerOption: configScannerOptions, MisconfScannerOption: configScannerOptions,
// For secret scanning // For secret scanning
SecretScannerOption: secret.ScannerOption{ SecretScannerOption: secret.ScannerOption{
ConfigPath: opt.SecretConfigPath, ConfigPath: opts.SecretConfigPath,
}, },
}, },
}, scanOptions, nil }, scanOptions, nil
} }
func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner, cacheClient cache.Cache) ( func scan(ctx context.Context, opts flag.Options, initializeScanner InitializeScanner, cacheClient cache.Cache) (
types.Report, error) { types.Report, error) {
scannerConfig, scanOptions, err := initScannerConfig(opt, cacheClient) scannerConfig, scanOptions, err := initScannerConfig(opts, cacheClient)
if err != nil { if err != nil {
return types.Report{}, err return types.Report{}, err
} }
@@ -517,8 +533,8 @@ func scan(ctx context.Context, opt Option, initializeScanner InitializeScanner,
return report, nil return report, nil
} }
func Exit(c Option, failedResults bool) { func Exit(opts flag.Options, failedResults bool) {
if c.ExitCode != 0 && failedResults { if opts.ExitCode != 0 && failedResults {
os.Exit(c.ExitCode) os.Exit(opts.ExitCode)
} }
} }

View File

@@ -1,33 +0,0 @@
package artifact
import (
"github.com/urfave/cli/v2"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/types"
)
// SbomRun runs generates sbom for image and package artifacts
func SbomRun(ctx *cli.Context) error {
opt, err := InitOption(ctx)
if err != nil {
return xerrors.Errorf("option error: %w", err)
}
artifactType := ArtifactType(opt.SbomOption.ArtifactType)
if !slices.Contains(supportedArtifactTypes, artifactType) {
return xerrors.Errorf(`"--artifact-type" must be %q`, supportedArtifactTypes)
}
// Pass the specified image archive via "--input".
if artifactType == imageArchiveArtifact {
opt.Input = opt.Target
}
// Scan the relevant dependencies
opt.ReportOption.VulnType = []string{types.VulnTypeOS, types.VulnTypeLibrary}
opt.ReportOption.SecurityChecks = []string{types.SecurityCheckVulnerability}
return run(ctx.Context, opt, artifactType)
}

View File

@@ -3,7 +3,6 @@ package artifact
import ( import (
"context" "context"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/scanner" "github.com/aquasecurity/trivy/pkg/scanner"
@@ -64,7 +63,47 @@ func archiveRemoteScanner(ctx context.Context, conf ScannerConfig) (scanner.Scan
return s, func() {}, nil return s, func() {}, nil
} }
// ImageRun runs scan on container image // filesystemStandaloneScanner initializes a filesystem scanner in standalone mode
func ImageRun(ctx *cli.Context) error { func filesystemStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
return Run(ctx, containerImageArtifact) s, cleanup, err := initializeFilesystemScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// filesystemRemoteScanner initializes a filesystem scanner in client/server mode
func filesystemRemoteScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeRemoteFilesystemScanner(ctx, conf.Target, conf.ArtifactCache, conf.RemoteOption, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// filesystemStandaloneScanner initializes a repository scanner in standalone mode
func repositoryStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeRepositoryScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a filesystem scanner: %w", err)
}
return s, cleanup, nil
}
// sbomStandaloneScanner initializes a SBOM scanner in standalone mode
func sbomStandaloneScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeSBOMScanner(ctx, conf.Target, conf.ArtifactCache, conf.LocalArtifactCache, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a cycloneDX scanner: %w", err)
}
return s, cleanup, nil
}
// sbomRemoteScanner initializes a SBOM scanner in client/server mode
func sbomRemoteScanner(ctx context.Context, conf ScannerConfig) (scanner.Scanner, func(), error) {
s, cleanup, err := initializeRemoteSBOMScanner(ctx, conf.Target, conf.ArtifactCache, conf.RemoteOption, conf.ArtifactOption)
if err != nil {
return scanner.Scanner{}, func() {}, xerrors.Errorf("unable to initialize a cycloneDX scanner: %w", err)
}
return s, cleanup, nil
} }

View File

@@ -8,7 +8,6 @@ package artifact
import ( import (
"context" "context"
"github.com/aquasecurity/trivy-db/pkg/db" "github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/detector/ospkg" "github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/fanal/applier" "github.com/aquasecurity/trivy/pkg/fanal/applier"
@@ -16,6 +15,7 @@ import (
image2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" image2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/image"
local2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/local" local2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/local"
"github.com/aquasecurity/trivy/pkg/fanal/artifact/remote" "github.com/aquasecurity/trivy/pkg/fanal/artifact/remote"
"github.com/aquasecurity/trivy/pkg/fanal/artifact/sbom"
"github.com/aquasecurity/trivy/pkg/fanal/cache" "github.com/aquasecurity/trivy/pkg/fanal/cache"
"github.com/aquasecurity/trivy/pkg/fanal/image" "github.com/aquasecurity/trivy/pkg/fanal/image"
"github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/fanal/types"
@@ -35,7 +35,8 @@ func initializeDockerScanner(ctx context.Context, imageName string, artifactCach
config := db.Config{} config := db.Config{}
client := vulnerability.NewClient(config) client := vulnerability.NewClient(config)
localScanner := local.NewScanner(applierApplier, detector, client) localScanner := local.NewScanner(applierApplier, detector, client)
typesImage, cleanup, err := image.NewContainerImage(ctx, imageName, dockerOpt) v := _wireValue
typesImage, cleanup, err := image.NewContainerImage(ctx, imageName, dockerOpt, v...)
if err != nil { if err != nil {
return scanner.Scanner{}, nil, err return scanner.Scanner{}, nil, err
} }
@@ -50,6 +51,10 @@ func initializeDockerScanner(ctx context.Context, imageName string, artifactCach
}, nil }, nil
} }
var (
_wireValue = []image.Option(nil)
)
// initializeArchiveScanner is for container image archive scanning in standalone mode // initializeArchiveScanner is for container image archive scanning in standalone mode
// e.g. docker save -o alpine.tar alpine:3.15 // e.g. docker save -o alpine.tar alpine:3.15
func initializeArchiveScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, artifactOption artifact.Option) (scanner.Scanner, error) { func initializeArchiveScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, artifactOption artifact.Option) (scanner.Scanner, error) {
@@ -102,12 +107,28 @@ func initializeRepositoryScanner(ctx context.Context, url string, artifactCache
}, nil }, nil
} }
func initializeSBOMScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
config := db.Config{}
client := vulnerability.NewClient(config)
localScanner := local.NewScanner(applierApplier, detector, client)
artifactArtifact, err := sbom.NewArtifact(filePath, artifactCache, artifactOption)
if err != nil {
return scanner.Scanner{}, nil, err
}
scannerScanner := scanner.NewScanner(localScanner, artifactArtifact)
return scannerScanner, func() {
}, nil
}
// initializeRemoteDockerScanner is for container image scanning in client/server mode // initializeRemoteDockerScanner is for container image scanning in client/server mode
// e.g. dockerd, container registry, podman, etc. // e.g. dockerd, container registry, podman, etc.
func initializeRemoteDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, dockerOpt types.DockerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) { func initializeRemoteDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, dockerOpt types.DockerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
v := _wireValue v := _wireValue2
clientScanner := client.NewScanner(remoteScanOptions, v...) clientScanner := client.NewScanner(remoteScanOptions, v...)
typesImage, cleanup, err := image.NewContainerImage(ctx, imageName, dockerOpt) v2 := _wireValue3
typesImage, cleanup, err := image.NewContainerImage(ctx, imageName, dockerOpt, v2...)
if err != nil { if err != nil {
return scanner.Scanner{}, nil, err return scanner.Scanner{}, nil, err
} }
@@ -123,13 +144,14 @@ func initializeRemoteDockerScanner(ctx context.Context, imageName string, artifa
} }
var ( var (
_wireValue = []client.Option(nil) _wireValue2 = []client.Option(nil)
_wireValue3 = []image.Option(nil)
) )
// initializeRemoteArchiveScanner is for container image archive scanning in client/server mode // initializeRemoteArchiveScanner is for container image archive scanning in client/server mode
// e.g. docker save -o alpine.tar alpine:3.15 // e.g. docker save -o alpine.tar alpine:3.15
func initializeRemoteArchiveScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, error) { func initializeRemoteArchiveScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, error) {
v := _wireValue v := _wireValue2
clientScanner := client.NewScanner(remoteScanOptions, v...) clientScanner := client.NewScanner(remoteScanOptions, v...)
typesImage, err := image.NewArchiveImage(filePath) typesImage, err := image.NewArchiveImage(filePath)
if err != nil { if err != nil {
@@ -145,7 +167,7 @@ func initializeRemoteArchiveScanner(ctx context.Context, filePath string, artifa
// initializeRemoteFilesystemScanner is for filesystem scanning in client/server mode // initializeRemoteFilesystemScanner is for filesystem scanning in client/server mode
func initializeRemoteFilesystemScanner(ctx context.Context, path string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) { func initializeRemoteFilesystemScanner(ctx context.Context, path string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
v := _wireValue v := _wireValue2
clientScanner := client.NewScanner(remoteScanOptions, v...) clientScanner := client.NewScanner(remoteScanOptions, v...)
artifactArtifact, err := local2.NewArtifact(path, artifactCache, artifactOption) artifactArtifact, err := local2.NewArtifact(path, artifactCache, artifactOption)
if err != nil { if err != nil {
@@ -155,3 +177,16 @@ func initializeRemoteFilesystemScanner(ctx context.Context, path string, artifac
return scannerScanner, func() { return scannerScanner, func() {
}, nil }, nil
} }
// initializeRemoteSBOMScanner is for sbom scanning in client/server mode
func initializeRemoteSBOMScanner(ctx context.Context, path string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) {
v := _wireValue2
clientScanner := client.NewScanner(remoteScanOptions, v...)
artifactArtifact, err := sbom.NewArtifact(path, artifactCache, artifactOption)
if err != nil {
return scanner.Scanner{}, nil, err
}
scannerScanner := scanner.NewScanner(clientScanner, artifactArtifact)
return scannerScanner, func() {
}, nil
}

View File

@@ -1,58 +0,0 @@
package module
import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/module"
)
// Install installs a module
func Install(c *cli.Context) error {
if c.NArg() != 1 {
cli.ShowSubcommandHelpAndExit(c, 1)
}
if err := initLogger(c); err != nil {
return xerrors.Errorf("log initialization error: %w", err)
}
repo := c.Args().First()
if err := module.Install(c.Context, repo, c.Bool("quiet"), c.Bool("insecure")); err != nil {
return xerrors.Errorf("module installation error: %w", err)
}
return nil
}
// Uninstall uninstalls a module
func Uninstall(c *cli.Context) error {
if c.NArg() != 1 {
cli.ShowSubcommandHelpAndExit(c, 1)
}
if err := initLogger(c); err != nil {
return xerrors.Errorf("log initialization error: %w", err)
}
repo := c.Args().First()
if err := module.Uninstall(c.Context, repo); err != nil {
return xerrors.Errorf("module uninstall error: %w", err)
}
return nil
}
func initLogger(ctx *cli.Context) error {
conf, err := option.NewGlobalOption(ctx)
if err != nil {
return xerrors.Errorf("config error: %w", err)
}
if err = log.InitLogger(conf.Debug, conf.Quiet); err != nil {
return xerrors.Errorf("failed to initialize a logger: %w", err)
}
return nil
}

View File

@@ -6,12 +6,15 @@ import (
"os" "os"
"strings" "strings"
"github.com/samber/lo"
"github.com/aquasecurity/trivy/pkg/flag"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"github.com/google/wire" "github.com/google/wire"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/aquasecurity/trivy-db/pkg/metadata" "github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/aquasecurity/trivy/pkg/db" "github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/fanal/cache" "github.com/aquasecurity/trivy/pkg/fanal/cache"
"github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/log"
@@ -31,7 +34,7 @@ type Cache struct {
} }
// NewCache is the factory method for Cache // NewCache is the factory method for Cache
func NewCache(c option.CacheOption) (Cache, error) { func NewCache(c flag.CacheOptions) (Cache, error) {
if strings.HasPrefix(c.CacheBackend, "redis://") { if strings.HasPrefix(c.CacheBackend, "redis://") {
log.Logger.Infof("Redis cache: %s", c.CacheBackendMasked()) log.Logger.Infof("Redis cache: %s", c.CacheBackendMasked())
options, err := redis.ParseURL(c.CacheBackend) options, err := redis.ParseURL(c.CacheBackend)
@@ -39,7 +42,7 @@ func NewCache(c option.CacheOption) (Cache, error) {
return Cache{}, err return Cache{}, err
} }
if (option.RedisOption{}) != c.RedisOption { if !lo.IsEmpty(c.RedisOptions) {
caCert, cert, err := utils.GetTLSConfig(c.RedisCACert, c.RedisCert, c.RedisKey) caCert, cert, err := utils.GetTLSConfig(c.RedisCACert, c.RedisCert, c.RedisKey)
if err != nil { if err != nil {
return Cache{}, err return Cache{}, err

View File

@@ -1,54 +0,0 @@
package option
import (
"os"
"time"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"golang.org/x/xerrors"
)
// ArtifactOption holds the options for an artifact scanning
type ArtifactOption struct {
Input string
Timeout time.Duration
ClearCache bool
SkipDirs []string
SkipFiles []string
OfflineScan bool
// this field is populated in Init()
Target string
}
// NewArtifactOption is the factory method to return artifact option
func NewArtifactOption(c *cli.Context) ArtifactOption {
return ArtifactOption{
Input: c.String("input"),
Timeout: c.Duration("timeout"),
ClearCache: c.Bool("clear-cache"),
SkipFiles: c.StringSlice("skip-files"),
SkipDirs: c.StringSlice("skip-dirs"),
OfflineScan: c.Bool("offline-scan"),
}
}
// Init initialize the CLI context for artifact scanning
func (c *ArtifactOption) Init(ctx *cli.Context, logger *zap.SugaredLogger) (err error) {
if c.Input == "" && ctx.Args().Len() == 0 {
logger.Debug(`trivy requires at least 1 argument or --input option`)
_ = cli.ShowSubcommandHelp(ctx) // nolint: errcheck
os.Exit(0)
} else if ctx.Args().Len() > 1 && ctx.Command.Name != "kubernetes" {
logger.Error(`multiple targets cannot be specified`)
return xerrors.New("arguments error")
}
if c.Input == "" {
c.Target = ctx.Args().First()
}
return nil
}

View File

@@ -1,73 +0,0 @@
package option_test
import (
"flag"
"testing"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"
)
func TestArtifactOption_Init(t *testing.T) {
tests := []struct {
name string
args []string
logs []string
want option.ArtifactOption
wantErr string
}{
{
name: "happy path",
args: []string{"alpine:3.10"},
want: option.ArtifactOption{
Target: "alpine:3.10",
},
},
{
name: "sad: multiple image names",
args: []string{"centos:7", "alpine:3.10"},
logs: []string{
"multiple targets cannot be specified",
},
wantErr: "arguments error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core, obs := observer.New(zap.DebugLevel)
logger := zap.New(core)
app := cli.NewApp()
set := flag.NewFlagSet("test", 0)
ctx := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
c := option.NewArtifactOption(ctx)
err := c.Init(ctx, logger.Sugar())
// tests log messages
var gotMessages []string
for _, entry := range obs.AllUntimed() {
gotMessages = append(gotMessages, entry.Message)
}
assert.Equal(t, tt.logs, gotMessages, tt.name)
// test the error
switch {
case tt.wantErr != "":
require.NotNil(t, err)
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
return
default:
assert.NoError(t, err, tt.name)
}
assert.Equal(t, tt.want, c, tt.name)
})
}
}

View File

@@ -1,66 +0,0 @@
package option
import (
"fmt"
"strings"
"time"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
)
// CacheOption holds the options for cache
type CacheOption struct {
CacheBackend string
CacheTTL time.Duration
RedisOption
}
// RedisOption holds the options for redis cache
type RedisOption struct {
RedisCACert string
RedisCert string
RedisKey string
}
// NewCacheOption returns an instance of CacheOption
func NewCacheOption(c *cli.Context) CacheOption {
return CacheOption{
CacheBackend: c.String("cache-backend"),
CacheTTL: c.Duration("cache-ttl"),
RedisOption: RedisOption{
RedisCACert: c.String("redis-ca"),
RedisCert: c.String("redis-cert"),
RedisKey: c.String("redis-key"),
},
}
}
// Init initialize the CacheOption
func (c *CacheOption) Init() error {
// "redis://" or "fs" are allowed for now
// An empty value is also allowed for testability
if !strings.HasPrefix(c.CacheBackend, "redis://") &&
c.CacheBackend != "fs" && c.CacheBackend != "" {
return xerrors.Errorf("unsupported cache backend: %s", c.CacheBackend)
}
// if one of redis option not nil, make sure CA, cert, and key provided
if (RedisOption{}) != c.RedisOption {
if c.RedisCACert == "" || c.RedisCert == "" || c.RedisKey == "" {
return xerrors.Errorf("you must provide CA, cert and key file path when using tls")
}
}
return nil
}
// CacheBackendMasked returns the redis connection string masking credentials
func (c *CacheOption) CacheBackendMasked() string {
endIndex := strings.Index(c.CacheBackend, "@")
if endIndex == -1 {
return c.CacheBackend
}
startIndex := strings.Index(c.CacheBackend, "//")
return fmt.Sprintf("%s****%s", c.CacheBackend[:startIndex+2], c.CacheBackend[endIndex:])
}

View File

@@ -1,127 +0,0 @@
package option_test
import (
"flag"
"testing"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
"github.com/aquasecurity/trivy/pkg/commands/option"
)
func TestNewCacheOption(t *testing.T) {
tests := []struct {
name string
args []string
want option.CacheOption
}{
{
name: "happy path",
args: []string{"--cache-backend", "redis://localhost:6379"},
want: option.CacheOption{
CacheBackend: "redis://localhost:6379",
},
},
{
name: "default",
args: []string{},
want: option.CacheOption{
CacheBackend: "fs",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
app := &cli.App{}
set := flag.NewFlagSet("test", 0)
set.String("cache-backend", "fs", "")
c := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
got := option.NewCacheOption(c)
assert.Equal(t, tt.want, got, tt.name)
})
}
}
func TestCacheOption_Init(t *testing.T) {
type fields struct {
backend string
}
tests := []struct {
name string
fields fields
wantErr string
}{
{
name: "fs",
fields: fields{
backend: "fs",
},
},
{
name: "redis",
fields: fields{
backend: "redis://localhost:6379",
},
},
{
name: "sad path",
fields: fields{
backend: "unknown://",
},
wantErr: "unsupported cache backend: unknown://",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &option.CacheOption{
CacheBackend: tt.fields.backend,
}
err := c.Init()
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestCacheOption_CacheBackendMasked(t *testing.T) {
type fields struct {
backend string
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "redis cache backend masked",
fields: fields{
backend: "redis://root:password@localhost:6379",
},
want: "redis://****@localhost:6379",
},
{
name: "redis cache backend masked does nothing",
fields: fields{
backend: "redis://localhost:6379",
},
want: "redis://localhost:6379",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &option.CacheOption{
CacheBackend: tt.fields.backend,
}
assert.Equal(t, tt.want, c.CacheBackendMasked())
})
}
}

View File

@@ -1,31 +0,0 @@
package option
import (
"github.com/urfave/cli/v2"
)
// ConfigOption holds the options for config scanning
type ConfigOption struct {
FilePatterns []string
IncludeNonFailures bool
SkipPolicyUpdate bool
Trace bool
// Rego
PolicyPaths []string
DataPaths []string
PolicyNamespaces []string
}
// NewConfigOption is the factory method to return config scanning options
func NewConfigOption(c *cli.Context) ConfigOption {
return ConfigOption{
IncludeNonFailures: c.Bool("include-non-failures"),
SkipPolicyUpdate: c.Bool("skip-policy-update"),
Trace: c.Bool("trace"),
FilePatterns: c.StringSlice("file-patterns"),
PolicyPaths: c.StringSlice("config-policy"),
DataPaths: c.StringSlice("config-data"),
PolicyNamespaces: c.StringSlice("policy-namespaces"),
}
}

View File

@@ -1,41 +0,0 @@
package option
import (
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/log"
)
// DBOption holds the options for trivy DB
type DBOption struct {
Reset bool
DownloadDBOnly bool
SkipDBUpdate bool
Light bool
NoProgress bool
DBRepository string
}
// NewDBOption is the factory method to return the DBOption
func NewDBOption(c *cli.Context) DBOption {
return DBOption{
Reset: c.Bool("reset"),
DownloadDBOnly: c.Bool("download-db-only"),
SkipDBUpdate: c.Bool("skip-db-update"),
Light: c.Bool("light"),
NoProgress: c.Bool("no-progress"),
DBRepository: c.String("db-repository"),
}
}
// Init initialize the DBOption
func (c *DBOption) Init() (err error) {
if c.SkipDBUpdate && c.DownloadDBOnly {
return xerrors.New("--skip-db-update and --download-db-only options can not be specified both")
}
if c.Light {
log.Logger.Warn("'--light' option is deprecated and will be removed. See also: https://github.com/aquasecurity/trivy/discussions/1649")
}
return nil
}

View File

@@ -1,87 +0,0 @@
package option_test
import (
"flag"
"testing"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
)
func TestNewDBOption(t *testing.T) {
tests := []struct {
name string
args []string
want option.DBOption
}{
{
name: "happy path",
args: []string{"--reset", "--skip-db-update"},
want: option.DBOption{
Reset: true,
SkipDBUpdate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
app := &cli.App{}
set := flag.NewFlagSet("test", 0)
set.Bool("reset", false, "")
set.Bool("skip-db-update", false, "")
c := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
got := option.NewDBOption(c)
assert.Equal(t, tt.want, got, tt.name)
})
}
}
func TestDBOption_Init(t *testing.T) {
type fields struct {
Reset bool
DownloadDBOnly bool
SkipUpdate bool
Light bool
}
tests := []struct {
name string
fields fields
wantErr string
}{
{
name: "happy path",
fields: fields{
Light: true,
},
},
{
name: "sad path",
fields: fields{
DownloadDBOnly: true,
SkipUpdate: true,
},
wantErr: "--skip-db-update and --download-db-only options can not be specified both",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &option.DBOption{
Reset: tt.fields.Reset,
DownloadDBOnly: tt.fields.DownloadDBOnly,
SkipDBUpdate: tt.fields.SkipUpdate,
Light: tt.fields.Light,
}
err := c.Init()
if tt.wantErr != "" {
assert.EqualError(t, err, tt.wantErr, err)
} else {
assert.NoError(t, err)
}
})
}
}

View File

@@ -1,40 +0,0 @@
package option
import (
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/log"
)
// GlobalOption holds the global options for trivy
type GlobalOption struct {
Context *cli.Context
Logger *zap.SugaredLogger
AppVersion string
Quiet bool
Debug bool
CacheDir string
}
// NewGlobalOption is the factory method to return GlobalOption
func NewGlobalOption(c *cli.Context) (GlobalOption, error) {
quiet := c.Bool("quiet")
debug := c.Bool("debug")
logger, err := log.NewLogger(debug, quiet)
if err != nil {
return GlobalOption{}, xerrors.New("failed to create a logger")
}
return GlobalOption{
Context: c,
Logger: logger,
AppVersion: c.App.Version,
Quiet: quiet,
Debug: debug,
CacheDir: c.String("cache-dir"),
}, nil
}

View File

@@ -1,45 +0,0 @@
package option_test
import (
"flag"
"testing"
"github.com/aquasecurity/trivy/pkg/commands/option"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
)
func TestNewGlobalConfig(t *testing.T) {
tests := []struct {
name string
args []string
want option.GlobalOption
}{
{
name: "happy path",
args: []string{"--quiet", "--debug"},
want: option.GlobalOption{
Quiet: true,
Debug: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
app := &cli.App{}
set := flag.NewFlagSet("test", 0)
set.Bool("debug", false, "")
set.Bool("quiet", false, "")
c := cli.NewContext(app, set, nil)
_ = set.Parse(tt.args)
got, err := option.NewGlobalOption(c)
require.NoError(t, err, err)
assert.Equal(t, tt.want.Quiet, got.Quiet, tt.name)
assert.Equal(t, tt.want.Debug, got.Debug, tt.name)
assert.Equal(t, tt.want.CacheDir, got.CacheDir, tt.name)
})
}
}

Some files were not shown because too many files have changed in this diff Show More