diff --git a/.gitignore b/.gitignore index 1dd36e7..006da11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .idea/ -*.test \ No newline at end of file +*.test +!test/data/*.test +trivyignores diff --git a/README.md b/README.md index 9b9fc28..3ba560e 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,11 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Build an image from Dockerfile run: | docker build -t docker.io/my-organization/my-app:${{ github.sha }} . - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -116,7 +116,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v1 - if: always() + if: always() with: sarif_file: 'trivy-results.sarif' ``` @@ -247,7 +247,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -256,7 +256,7 @@ jobs: output: 'trivy-results.sarif' env: TRIVY_USERNAME: Username - TRIVY_PASSWORD: Password + TRIVY_PASSWORD: Password - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v1 @@ -283,7 +283,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -319,7 +319,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -352,7 +352,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: @@ -361,7 +361,7 @@ jobs: output: 'trivy-results.sarif' env: TRIVY_USERNAME: Username - TRIVY_PASSWORD: Password + TRIVY_PASSWORD: Password - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v1 @@ -395,6 +395,7 @@ Following inputs can be used as `step.with` keys: | `ignore-policy` | String | | Filter vulnerabilities with OPA rego language | | `list-all-pkgs` | String | | Output all packages regardless of vulnerability | | `security-checks`| String | `vuln,secret` | comma-separated list of what security issues to detect (`vuln`,`secret`,`config`)| +| `trivyignores` | String | | comma-separated list of relative paths in repository to one or more `.trivyignore` files | [release]: https://github.com/aquasecurity/trivy-action/releases/latest [release-img]: https://img.shields.io/github/release/aquasecurity/trivy-action.svg?logo=github diff --git a/action.yaml b/action.yaml index 03a22a9..18c9495 100644 --- a/action.yaml +++ b/action.yaml @@ -77,6 +77,10 @@ inputs: description: 'comma-separated list of what security issues to detect' required: false default: '' + trivyignores: + description: 'comma-separated list of relative paths in repository to one or more .trivyignore files' + required: false + default: '' runs: using: 'docker' image: "Dockerfile" @@ -100,3 +104,4 @@ runs: - '-q ${{ inputs.skip-files }}' - '-r ${{ inputs.list-all-pkgs }}' - '-s ${{ inputs.security-checks }}' + - '-t ${{ inputs.trivyignores }}' diff --git a/entrypoint.sh b/entrypoint.sh index a02efa8..7529aba 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:" o; do +while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:" o; do case "${o}" in a) export scanType=${OPTARG} @@ -59,6 +59,9 @@ while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:" o; do s) export securityChecks=${OPTARG} ;; + t) + export trivyIgnores=${OPTARG} + ;; esac done @@ -114,6 +117,20 @@ if [ $skipDirs ];then SARIF_ARGS="$SARIF_ARGS --skip-dirs $i" done fi +if [ $trivyIgnores ];then + for f in $(echo $trivyIgnores | tr "," "\n") + do + if [ -f "$f" ]; then + echo "Found ignorefile '${f}':" + cat "${f}" + cat "${f}" >> ./trivyignores + else + echo "ERROR: cannot find ignorefile '${f}'." + exit 1 + fi + done + ARGS="$ARGS --ignorefile ./trivyignores" +fi if [ $timeout ];then ARGS="$ARGS --timeout $timeout" fi diff --git a/test/data/.trivyignore1 b/test/data/.trivyignore1 new file mode 100644 index 0000000..9fb1ac2 --- /dev/null +++ b/test/data/.trivyignore1 @@ -0,0 +1,3 @@ +# test data #1 for trivy-ignores option +CVE-2020-25576 +CVE-2019-15551 diff --git a/test/data/.trivyignore2 b/test/data/.trivyignore2 new file mode 100644 index 0000000..535cb38 --- /dev/null +++ b/test/data/.trivyignore2 @@ -0,0 +1,2 @@ +# test data #2 for trivy-ignores option +CVE-2019-15554 diff --git a/test/data/image-trivyignores.test b/test/data/image-trivyignores.test new file mode 100644 index 0000000..3bb3ad6 --- /dev/null +++ b/test/data/image-trivyignores.test @@ -0,0 +1,92 @@ ++-------------+------------------+----------+-------------------+---------------+---------------------------------------+ +| LIBRARY | VULNERABILITY ID | 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 | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-14618 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2018-16839 | | | 7.61.1-r1 | curl: Integer overflow leading | +| | | | | | to heap-based buffer overflow in | +| | | | | | Curl_sasl_create_plain_message() | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16839 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2018-16840 | | | | curl: Use-after-free when closing | +| | | | | | "easy" handle in Curl_close() | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16840 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2018-16842 | | | | curl: Heap-based buffer over-read | +| | | | | | in the curl tool warning formatting | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16842 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2019-3822 | | | 7.61.1-r2 | curl: NTLMv2 type-3 header | +| | | | | | stack buffer overflow | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-3822 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2019-5481 | | | 7.61.1-r3 | curl: double free due to | +| | | | | | subsequent call of realloc() | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-5481 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2019-5482 | | | | curl: heap buffer overflow in | +| | | | | | function tftp_receive_packet() | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-5482 | ++-------------+------------------+ +-------------------+---------------+---------------------------------------+ +| git | CVE-2018-17456 | | 2.15.2-r0 | 2.15.3-r0 | git: arbitrary code | +| | | | | | execution via .gitmodules | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-17456 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2019-1353 | | | 2.15.4-r0 | git: NTFS protections inactive | +| | | | | | when running Git in the | +| | | | | | Windows Subsystem for... | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-1353 | ++-------------+------------------+ +-------------------+---------------+---------------------------------------+ +| libbz2 | CVE-2019-12900 | | 1.0.6-r6 | 1.0.6-r7 | bzip2: out-of-bounds write | +| | | | | | in function BZ2_decompress | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-12900 | ++-------------+------------------+ +-------------------+---------------+---------------------------------------+ +| libcurl | CVE-2018-16839 | | 7.61.1-r0 | 7.61.1-r1 | curl: Integer overflow leading | +| | | | | | to heap-based buffer overflow in | +| | | | | | Curl_sasl_create_plain_message() | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16839 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2018-16840 | | | | curl: Use-after-free when closing | +| | | | | | "easy" handle in Curl_close() | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16840 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2018-16842 | | | | curl: Heap-based buffer over-read | +| | | | | | in the curl tool warning formatting | +| | | | | | -->avd.aquasec.com/nvd/cve-2018-16842 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2019-3822 | | | 7.61.1-r2 | curl: NTLMv2 type-3 header | +| | | | | | stack buffer overflow | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-3822 | ++ +------------------+ + +---------------+---------------------------------------+ +| | CVE-2019-5481 | | | 7.61.1-r3 | curl: double free due to | +| | | | | | subsequent call of realloc() | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-5481 | ++ +------------------+ + + +---------------------------------------+ +| | CVE-2019-5482 | | | | curl: heap buffer overflow in | +| | | | | | function tftp_receive_packet() | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-5482 | ++-------------+------------------+ +-------------------+---------------+---------------------------------------+ +| musl | CVE-2019-14697 | | 1.1.18-r3 | 1.1.18-r4 | musl libc through 1.1.23 | +| | | | | | has an x87 floating-point | +| | | | | | stack adjustment im ...... | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-14697 | ++-------------+ + + + + + +| musl-utils | | | | | | +| | | | | | | +| | | | | | | +| | | | | | | ++-------------+------------------+ +-------------------+---------------+---------------------------------------+ +| sqlite-libs | CVE-2019-8457 | | 3.21.0-r1 | 3.25.3-r1 | sqlite: heap out-of-bound | +| | | | | | read in function rtreenode() | +| | | | | | -->avd.aquasec.com/nvd/cve-2019-8457 | ++-------------+------------------+----------+-------------------+---------------+---------------------------------------+ ++----------+------------------+----------+-------------------+---------------+---------------------------------------+ +| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | ++----------+------------------+----------+-------------------+---------------+---------------------------------------+ +| smallvec | CVE-2021-25900 | CRITICAL | 0.6.9 | 0.6.14, 1.6.1 | An issue was discovered | +| | | | | | in the smallvec crate | +| | | | | | before 0.6.14 and 1.x... | +| | | | | | -->avd.aquasec.com/nvd/cve-2021-25900 | ++----------+------------------+----------+-------------------+---------------+---------------------------------------+ diff --git a/test/test.bats b/test/test.bats index 8e58ea6..a8bccca 100644 --- a/test/test.bats +++ b/test/test.bats @@ -1,50 +1,57 @@ #!/usr/bin/env bats @test "trivy image" { - # trivy image --severity CRITICAL -o image.test knqyf263/vuln-image:1.2.3 + # trivy image --severity CRITICAL --output image.test knqyf263/vuln-image:1.2.3 ./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-b table' '-h image.test' '-g CRITICAL' result="$(diff ./test/data/image.test image.test)" [ "$result" == '' ] } @test "trivy image sarif report" { - # trivy image --severity CRITICAL -f sarif -o image-sarif.test knqyf263/vuln-image:1.2.3 + # trivy image --severity CRITICAL -f sarif --output image-sarif.test knqyf263/vuln-image:1.2.3 ./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-b sarif' '-h image-sarif.test' '-g CRITICAL' result="$(diff ./test/data/image-sarif.test image-sarif.test)" [ "$result" == '' ] } @test "trivy config" { - # trivy conf -o config.test . + # trivy conf --output config.test . ./entrypoint.sh '-a config' '-j .' '-b table' '-h config.test' result="$(diff ./test/data/config.test config.test)" [ "$result" == '' ] } @test "trivy rootfs" { - # trivy rootfs -o rootfs.test -f json . + # trivy rootfs --output rootfs.test -f json . ./entrypoint.sh '-a rootfs' '-j .' '-b json' '-h rootfs.test' result="$(diff ./test/data/rootfs.test rootfs.test)" [ "$result" == '' ] } @test "trivy fs" { - # trivy fs -f json -o fs.test . + # trivy fs -f json --output fs.test . ./entrypoint.sh '-a fs' '-j .' '-b json' '-h fs.test' result="$(diff ./test/data/fs.test fs.test)" [ "$result" == '' ] } @test "trivy fs with securityChecks option" { - # trivy fs -f json --security-checks=vuln,config -o fs.test . + # trivy fs -f json --security-checks=vuln,config --output fs.test . ./entrypoint.sh '-a fs' '-j .' '-b json' '-s vuln,config,secret' '-h fs-scheck.test' result="$(diff ./test/data/fs.test fs.test)" [ "$result" == '' ] } @test "trivy repo with securityCheck secret only" { - # trivy repo -f json -o repo.test --security-checks=secret https://github.com/krol3/demo-trivy/ + # trivy repo -f json --output repo.test --security-checks=secret https://github.com/krol3/demo-trivy/ ./entrypoint.sh '-b json' '-h repo.test' '-s secret' '-a repo' '-j https://github.com/krol3/demo-trivy/' result="$(diff ./test/data/repo.test repo.test)" [ "$result" == '' ] -} \ No newline at end of file +} + +@test "trivy image with trivyIgnores option" { + # cat ./test/data/.trivyignore1 ./test/data/.trivyignore2 > ./trivyignores ; trivy image --severity CRITICAL --output image-trivyignores.test --ignorefile ./trivyignores knqyf263/vuln-image:1.2.3 + ./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-b table' '-h image-trivyignores.test' '-g CRITICAL' '-t ./test/data/.trivyignore1,./test/data/.trivyignore2' + result="$(diff ./test/data/image-trivyignores.test image-trivyignores.test)" + [ "$result" == '' ] +}