Compare commits

..

17 Commits

Author SHA1 Message Date
Falk Puschner 8bd2f9fbda ⬆️ bump trivy action (#203) 2023-02-10 16:20:50 +09:00
simar7 cff3e9a7f6 feat(trivy): Bump Trivy to v0.37.1 (#199)
Signed-off-by: Simar <simar@linux.com>
2023-02-01 16:40:29 -08:00
Michael Cantú ab15891596 Update README.md (#186)
Fix typo
2023-02-01 16:23:59 -08:00
Omar Silva cacfd7a243 docs: add trivy-config to table (#195) 2023-02-01 16:19:16 -08:00
AndreyLevchenko 1e0bef4613 fix(sarif): Add option to limit severities for sarif (aquasecurity#192) (#198) 2023-02-01 16:18:31 -08:00
Aibek 9ab158e859 Add 0.34.0 release (#177)
* bump to ghcr.io/aquasecurity/trivy:0.33.0

* fix tests

* bump to 0.34.0
2022-10-31 17:18:27 -07:00
Lior Vaisman Argon e55de85bee Add npm to action Dockerfile (#176) 2022-10-25 07:04:22 -07:00
chejn d63413b0a4 Fix github dependency submission API call (#162)
* Update entrypoint.sh

* Update entrypoint.sh

* Update entrypoint.sh
2022-08-17 14:54:57 -07:00
simar7 1db49f5326 feat(trivy): Bump Trivy to v0.31.0 (#165)
Fixes: https://github.com/aquasecurity/trivy-action/issues/164

Signed-off-by: Simar <simar@linux.com>

Signed-off-by: Simar <simar@linux.com>
2022-08-16 17:25:38 -07:00
Engin Diri 12814ff8bc docs: correct format and add output on config scan with sarif (#159) 2022-08-15 11:09:42 -07:00
simar7 cb606dfdb0 fix(sarif): Add timeout and security-checks for sarif (#156) 2022-08-03 17:32:25 -07:00
Carol Valencia 0d7cf2ddfb chore: improve message output sbom with gh (#145)
* fix: merge with master- entrypoint

* chore: gitignore .vscode

Co-authored-by: carolina valencia <krol3@users.noreply.github.com>
2022-08-02 15:24:58 -07:00
simar7 5144f05a8d fix(config): Drop mixing of options with yaml config. (#148)
Also adds some documentation explaining how the config
and flags are used in conjunction with each other.

Fixes: https://github.com/aquasecurity/trivy-action/issues/147

Signed-off-by: Simar <simar@linux.com>
2022-07-29 14:30:07 -07:00
simar7 81b9a6f5ab Update Dockerfile (#152) 2022-07-26 13:08:58 -07:00
simar7 503d3abc15 feat(yaml): Add support for trivy.yaml (#143)
* feat(yaml): Add support for trivy.yaml

Signed-off-by: Simar <simar@linux.com>

* chore: fixing test using trivy v 0.30.0

* chore(deps): Update to use Trivy v0.30.2

Signed-off-by: Simar <simar@linux.com>

Co-authored-by: carolina valencia <krol3@users.noreply.github.com>
2022-07-21 16:36:46 -07:00
simar7 0105373003 docs(trivy): Add instructions to scan tarballs. (#134)
Signed-off-by: Simar <simar@linux.com>
2022-06-29 14:34:09 -07:00
simar7 bc615ae2d7 fix(tests): Update test golden files for Trivy v0.29.2 (#136)
Fixes: https://github.com/aquasecurity/trivy-action/issues/133
Fixes: https://github.com/aquasecurity/trivy-action/issues/135

Signed-off-by: Simar <simar@linux.com>
2022-06-29 14:33:23 -07:00
20 changed files with 750 additions and 6298 deletions
+4 -3
View File
@@ -1,7 +1,8 @@
name: "build" name: "build"
on: [push, pull_request] on: [push, pull_request]
env: env:
TRIVY_VERSION: 0.29.1 TRIVY_VERSION: 0.37.2
BATS_LIB_PATH: '/usr/lib/'
jobs: jobs:
build: build:
name: build name: build
@@ -11,7 +12,7 @@ jobs:
- name: Setup BATS - name: Setup BATS
uses: mig4/setup-bats@v1 uses: mig4/setup-bats@v1
with: with:
bats-version: 1.2.1 bats-version: 1.7.0
- name: Setup Bats libs - name: Setup Bats libs
uses: brokenpip3/setup-bats-libs@0.1.0 uses: brokenpip3/setup-bats-libs@0.1.0
@@ -24,4 +25,4 @@ jobs:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v${{ env.TRIVY_VERSION }} curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v${{ env.TRIVY_VERSION }}
- name: Test - name: Test
run: bats -r . run: BATS_LIB_PATH=${{ env.BATS_LIB_PATH }} bats --recursive --timing .
+1
View File
@@ -2,3 +2,4 @@
*.test *.test
!test/data/*.test !test/data/*.test
trivyignores trivyignores
.vscode/
+2 -2
View File
@@ -1,5 +1,5 @@
FROM ghcr.io/aquasecurity/trivy:0.29.1 FROM ghcr.io/aquasecurity/trivy:0.37.2
COPY entrypoint.sh / COPY entrypoint.sh /
RUN apk --no-cache add bash curl RUN apk --no-cache add bash curl npm
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
+4
View File
@@ -0,0 +1,4 @@
.PHONY: test
test:
BATS_LIB_PATH=/usr/local/lib/ bats -r .
+97 -24
View File
@@ -19,7 +19,7 @@
## Usage ## Usage
### Workflow ### Scan CI Pipeline
```yaml ```yaml
name: build name: build
@@ -31,15 +31,13 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Build an image from Dockerfile - name: Build an image from Dockerfile
run: | run: |
docker build -t docker.io/my-organization/my-app:${{ github.sha }} . docker build -t docker.io/my-organization/my-app:${{ github.sha }} .
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
with: with:
@@ -51,6 +49,78 @@ jobs:
severity: 'CRITICAL,HIGH' severity: 'CRITICAL,HIGH'
``` ```
### Scan CI Pipeline (w/ Trivy Config)
```yaml
name: build
on:
push:
branches:
- master
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner in fs mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
trivy-config: trivy.yaml
```
In this case `trivy.yaml` is a YAML configuration that is checked in as part of the repo. Detailed information is available on the Trivy website but an example is as follows:
```yaml
format: json
exit-code: 1
severity: CRITICAL
```
It is possible to define all options in the `trivy.yaml` file. Specifying individual options via the action are left for backward compatibility purposes. Defining the following is required as they cannot be defined with the config file:
- `scan-ref`: If using `fs, repo` scans.
- `image-ref`: If using `image` scan.
- `scan-type`: To define the scan type, e.g. `image`, `fs`, `repo`, etc.
#### Order of prerference for options
Trivy uses [Viper](https://github.com/spf13/viper) which has a defined precedence order for options. The order is as follows:
- GitHub Action flag
- Environment variable
- Config file
- Default
### Scanning a Tarball
```yaml
name: build
on:
push:
branches:
- master
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Generate tarball from image
run: |
docker pull <your-docker-image>
docker save -o vuln-image.tar <your-docker-image>
- name: Run Trivy vulnerability scanner in tarball mode
uses: aquasecurity/trivy-action@master
with:
input: /github/workspace/vuln-image.tar
severity: 'CRITICAL,HIGH'
```
### Using Trivy with GitHub Code Scanning ### Using Trivy with GitHub Code Scanning
If you have [GitHub code scanning](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) available you can use Trivy as a scanning tool as follows: If you have [GitHub code scanning](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) available you can use Trivy as a scanning tool as follows:
```yaml ```yaml
@@ -63,10 +133,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Build an image from Dockerfile - name: Build an image from Dockerfile
run: | run: |
@@ -98,10 +168,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Build an image from Dockerfile - name: Build an image from Dockerfile
run: | run: |
@@ -137,10 +207,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner in repo mode - name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -171,10 +241,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner with rootfs command - name: Run Trivy vulnerability scanner with rootfs command
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -192,7 +262,7 @@ jobs:
sarif_file: 'trivy-results.sarif' sarif_file: 'trivy-results.sarif'
``` ```
### Using Trivy to scan Infrastucture as Code ### Using Trivy to scan Infrastructure as Code
It's also possible to scan your IaC repos with Trivy's built-in repo scan. This can be handy if you want to run Trivy as a build time check on each PR that gets opened in your repo. This helps you identify potential vulnerablites that might get introduced with each PR. It's also possible to scan your IaC repos with Trivy's built-in repo scan. This can be handy if you want to run Trivy as a build time check on each PR that gets opened in your repo. This helps you identify potential vulnerablites that might get introduced with each PR.
If you have [GitHub code scanning](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) available you can use Trivy as a scanning tool as follows: If you have [GitHub code scanning](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) available you can use Trivy as a scanning tool as follows:
@@ -206,17 +276,18 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner in IaC mode - name: Run Trivy vulnerability scanner in IaC mode
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
with: with:
scan-type: 'config' scan-type: 'config'
hide-progress: false hide-progress: false
format: 'table' format: 'sarif'
output: 'trivy-results.sarif'
exit-code: '1' exit-code: '1'
ignore-unfixed: true ignore-unfixed: true
severity: 'CRITICAL,HIGH' severity: 'CRITICAL,HIGH'
@@ -275,10 +346,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -311,10 +382,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -347,10 +418,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -380,10 +451,10 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
@@ -429,7 +500,9 @@ Following inputs can be used as `step.with` keys:
| `list-all-pkgs` | String | | Output all packages regardless of vulnerability | | `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`) | | `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 | | `trivyignores` | String | | comma-separated list of relative paths in repository to one or more `.trivyignore` files |
| `trivy-config` | String | | Path to trivy.yaml config |
| `github-pat` | String | | GitHub Personal Access Token (PAT) for sending SBOM scan results to GitHub Dependency Snapshots | | `github-pat` | String | | GitHub Personal Access Token (PAT) for sending SBOM scan results to GitHub Dependency Snapshots |
| `limit-severities-for-sarif` | Boolean | false | By default *SARIF* format enforces output of all vulnerabilities regardless of configured severities. To override this behavior set this parameter to **true** |
[release]: https://github.com/aquasecurity/trivy-action/releases/latest [release]: https://github.com/aquasecurity/trivy-action/releases/latest
[release-img]: https://img.shields.io/github/release/aquasecurity/trivy-action.svg?logo=github [release-img]: https://img.shields.io/github/release/aquasecurity/trivy-action.svg?logo=github
+8
View File
@@ -85,6 +85,12 @@ inputs:
github-pat: github-pat:
description: 'GitHub Personal Access Token (PAT) for submitting SBOM to GitHub Dependency Snapshot API' description: 'GitHub Personal Access Token (PAT) for submitting SBOM to GitHub Dependency Snapshot API'
required: false required: false
trivy-config:
description: 'path to trivy.yaml config'
required: false
limit-severities-for-sarif:
description: 'limit severities for SARIF format'
required: false
runs: runs:
using: 'docker' using: 'docker'
@@ -111,3 +117,5 @@ runs:
- '-s ${{ inputs.security-checks }}' - '-s ${{ inputs.security-checks }}'
- '-t ${{ inputs.trivyignores }}' - '-t ${{ inputs.trivyignores }}'
- '-u ${{ inputs.github-pat }}' - '-u ${{ inputs.github-pat }}'
- '-v ${{ inputs.trivy-config }}'
- '-z ${{ inputs.limit-severities-for-sarif }}'
+33 -14
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:" o; do while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:z:" o; do
case "${o}" in case "${o}" in
a) a)
export scanType=${OPTARG} export scanType=${OPTARG}
@@ -65,9 +65,16 @@ while getopts "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:" o; do
u) u)
export githubPAT=${OPTARG} export githubPAT=${OPTARG}
;; ;;
v)
export trivyConfig=${OPTARG}
;;
z)
export limitSeveritiesForSARIF=${OPTARG}
;;
esac esac
done done
scanType=$(echo $scanType | tr -d '\r') scanType=$(echo $scanType | tr -d '\r')
export artifactRef="${imageRef}" export artifactRef="${imageRef}"
if [ "${scanType}" = "repo" ] || [ "${scanType}" = "fs" ] || [ "${scanType}" = "config" ] || [ "${scanType}" = "rootfs" ];then if [ "${scanType}" = "repo" ] || [ "${scanType}" = "fs" ] || [ "${scanType}" = "config" ] || [ "${scanType}" = "rootfs" ];then
@@ -77,8 +84,10 @@ input=$(echo $input | tr -d '\r')
if [ $input ]; then if [ $input ]; then
artifactRef="--input $input" artifactRef="--input $input"
fi fi
#trim leading spaces for boolean params
ignoreUnfixed=$(echo $ignoreUnfixed | tr -d '\r') ignoreUnfixed=$(echo $ignoreUnfixed | tr -d '\r')
hideProgress=$(echo $hideProgress | tr -d '\r') hideProgress=$(echo $hideProgress | tr -d '\r')
limitSeveritiesForSARIF=$(echo $limitSeveritiesForSARIF | tr -d '\r')
GLOBAL_ARGS="" GLOBAL_ARGS=""
if [ $cacheDir ];then if [ $cacheDir ];then
@@ -107,6 +116,7 @@ if [ $vulnType ] && [ "$scanType" != "config" ] && [ "$scanType" != "sbom" ];the
fi fi
if [ $securityChecks ];then if [ $securityChecks ];then
ARGS="$ARGS --security-checks $securityChecks" ARGS="$ARGS --security-checks $securityChecks"
SARIF_ARGS="$SARIF_ARGS --security-checks $securityChecks"
fi fi
if [ $severity ];then if [ $severity ];then
ARGS="$ARGS --severity $severity" ARGS="$ARGS --severity $severity"
@@ -137,6 +147,7 @@ if [ $trivyIgnores ];then
fi fi
if [ $timeout ];then if [ $timeout ];then
ARGS="$ARGS --timeout $timeout" ARGS="$ARGS --timeout $timeout"
SARIF_ARGS="$SARIF_ARGS --timeout $timeout"
fi fi
if [ $ignorePolicy ];then if [ $ignorePolicy ];then
ARGS="$ARGS --ignore-policy $ignorePolicy" ARGS="$ARGS --ignore-policy $ignorePolicy"
@@ -157,23 +168,31 @@ if [ "$skipFiles" ];then
done done
fi fi
echo "Running trivy with options: ${ARGS}" "${artifactRef}" trivyConfig=$(echo $trivyConfig | tr -d '\r')
echo "Global options: " "${GLOBAL_ARGS}" if [ "${format}" == "sarif" ] && [ "${limitSeveritiesForSARIF}" != "true" ]; then
trivy $GLOBAL_ARGS ${scanType} $ARGS ${artifactRef} # SARIF is special. We output all vulnerabilities,
returnCode=$? # regardless of severity level specified in this report.
# This is a feature, not a bug :)
# SARIF is special. We output all vulnerabilities,
# regardless of severity level specified in this report.
# This is a feature, not a bug :)
if [[ "${format}" == "sarif" ]]; then
echo "Building SARIF report with options: ${SARIF_ARGS}" "${artifactRef}" echo "Building SARIF report with options: ${SARIF_ARGS}" "${artifactRef}"
trivy --quiet ${scanType} --format sarif --output ${output} $SARIF_ARGS ${artifactRef} trivy --quiet ${scanType} --format sarif --output ${output} $SARIF_ARGS ${artifactRef}
elif [ $trivyConfig ]; then
echo "Running Trivy with trivy.yaml config from: " $trivyConfig
trivy --config $trivyConfig ${scanType} ${artifactRef}
returnCode=$?
else
echo "Running trivy with options: trivy ${scanType} ${ARGS}" "${artifactRef}"
echo "Global options: " "${GLOBAL_ARGS}"
trivy $GLOBAL_ARGS ${scanType} ${ARGS} ${artifactRef}
returnCode=$?
fi fi
if [[ "${format}" == "github" ]] && [[ "$(echo $githubPAT | xargs)" != "" ]]; then if [[ "${format}" == "github" ]]; then
echo "Uploading GitHub Dependency Snapshot" if [[ "$(echo $githubPAT | xargs)" != "" ]]; then
curl -u "${githubPAT}" -H 'Content-Type: application/json' 'https://api.github.com/repos/'$GITHUB_REPOSITORY'/dependency-graph/snapshots' -d @./$(echo $output | xargs) printf "\n Uploading GitHub Dependency Snapshot"
curl -H 'Accept: application/vnd.github+json' -H "Authorization: token $githubPAT" 'https://api.github.com/repos/'$GITHUB_REPOSITORY'/dependency-graph/snapshots' -d @./$(echo $output | xargs)
else
printf "\n Failing GitHub Dependency Snapshot. Missing github-pat"
fi
fi fi
echo "returnCode: " $returnCode
exit $returnCode exit $returnCode
+134
View File
@@ -0,0 +1,134 @@
{
"version": "2.1.0",
"$schema": "https://json.schemastore.org/sarif-2.1.0-rtm.5.json",
"runs": [
{
"tool": {
"driver": {
"fullName": "Trivy Vulnerability Scanner",
"informationUri": "https://github.com/aquasecurity/trivy",
"name": "Trivy",
"rules": [
{
"id": "DS002",
"name": "Misconfiguration",
"shortDescription": {
"text": "Image user should not be \u0026#39;root\u0026#39;"
},
"fullDescription": {
"text": "Running containers with \u0026#39;root\u0026#39; user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a \u0026#39;USER\u0026#39; statement to the Dockerfile."
},
"defaultConfiguration": {
"level": "error"
},
"helpUri": "https://avd.aquasec.com/misconfig/ds002",
"help": {
"text": "Misconfiguration DS002\nType: Dockerfile Security Check\nSeverity: HIGH\nCheck: Image user should not be 'root'\nMessage: Specify at least 1 USER command in Dockerfile with non-root user as argument\nLink: [DS002](https://avd.aquasec.com/misconfig/ds002)\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",
"markdown": "**Misconfiguration DS002**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|Dockerfile Security Check|HIGH|Image user should not be 'root'|Specify at least 1 USER command in Dockerfile with non-root user as argument|[DS002](https://avd.aquasec.com/misconfig/ds002)|\n\nRunning containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile."
},
"properties": {
"precision": "very-high",
"security-severity": "8.0",
"tags": [
"misconfiguration",
"security",
"HIGH"
]
}
},
{
"id": "DS026",
"name": "Misconfiguration",
"shortDescription": {
"text": "No HEALTHCHECK defined"
},
"fullDescription": {
"text": "You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers."
},
"defaultConfiguration": {
"level": "note"
},
"helpUri": "https://avd.aquasec.com/misconfig/ds026",
"help": {
"text": "Misconfiguration DS026\nType: Dockerfile Security Check\nSeverity: LOW\nCheck: No HEALTHCHECK defined\nMessage: Add HEALTHCHECK instruction in your Dockerfile\nLink: [DS026](https://avd.aquasec.com/misconfig/ds026)\nYou shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.",
"markdown": "**Misconfiguration DS026**\n| Type | Severity | Check | Message | Link |\n| --- | --- | --- | --- | --- |\n|Dockerfile Security Check|LOW|No HEALTHCHECK defined|Add HEALTHCHECK instruction in your Dockerfile|[DS026](https://avd.aquasec.com/misconfig/ds026)|\n\nYou shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers."
},
"properties": {
"precision": "very-high",
"security-severity": "2.0",
"tags": [
"misconfiguration",
"security",
"LOW"
]
}
}
],
"version": "0.37.2"
}
},
"results": [
{
"ruleId": "DS002",
"ruleIndex": 0,
"level": "error",
"message": {
"text": "Artifact: Dockerfile\nType: dockerfile\nVulnerability DS002\nSeverity: HIGH\nMessage: Specify at least 1 USER command in Dockerfile with non-root user as argument\nLink: [DS002](https://avd.aquasec.com/misconfig/ds002)"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "Dockerfile",
"uriBaseId": "ROOTPATH"
},
"region": {
"startLine": 1,
"startColumn": 1,
"endLine": 1,
"endColumn": 1
}
},
"message": {
"text": "Dockerfile"
}
}
]
},
{
"ruleId": "DS026",
"ruleIndex": 1,
"level": "note",
"message": {
"text": "Artifact: Dockerfile\nType: dockerfile\nVulnerability DS026\nSeverity: LOW\nMessage: Add HEALTHCHECK instruction in your Dockerfile\nLink: [DS026](https://avd.aquasec.com/misconfig/ds026)"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "Dockerfile",
"uriBaseId": "ROOTPATH"
},
"region": {
"startLine": 1,
"startColumn": 1,
"endLine": 1,
"endColumn": 1
}
},
"message": {
"text": "Dockerfile"
}
}
]
}
],
"columnKind": "utf16CodeUnits",
"originalUriBaseIds": {
"ROOTPATH": {
"uri": "file:///"
}
}
}
]
}
+29 -2
View File
@@ -20,14 +20,15 @@
"Class": "config", "Class": "config",
"Type": "dockerfile", "Type": "dockerfile",
"MisconfSummary": { "MisconfSummary": {
"Successes": 21, "Successes": 22,
"Failures": 1, "Failures": 2,
"Exceptions": 0 "Exceptions": 0
}, },
"Misconfigurations": [ "Misconfigurations": [
{ {
"Type": "Dockerfile Security Check", "Type": "Dockerfile Security Check",
"ID": "DS002", "ID": "DS002",
"AVDID": "AVD-DS-0002",
"Title": "Image user should not be 'root'", "Title": "Image user should not be 'root'",
"Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", "Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",
"Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument", "Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument",
@@ -49,6 +50,32 @@
"Lines": null "Lines": null
} }
} }
},
{
"Type": "Dockerfile Security Check",
"ID": "DS026",
"AVDID": "AVD-DS-0026",
"Title": "No HEALTHCHECK defined",
"Description": "You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.",
"Message": "Add HEALTHCHECK instruction in your Dockerfile",
"Namespace": "builtin.dockerfile.DS026",
"Query": "data.builtin.dockerfile.DS026.deny",
"Resolution": "Add HEALTHCHECK instruction in Dockerfile",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds026",
"References": [
"https://blog.aquasec.com/docker-security-best-practices",
"https://avd.aquasec.com/misconfig/ds026"
],
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Provider": "Dockerfile",
"Service": "general",
"Code": {
"Lines": null
}
}
} }
] ]
} }
+29 -2
View File
@@ -20,14 +20,15 @@
"Class": "config", "Class": "config",
"Type": "dockerfile", "Type": "dockerfile",
"MisconfSummary": { "MisconfSummary": {
"Successes": 21, "Successes": 22,
"Failures": 1, "Failures": 2,
"Exceptions": 0 "Exceptions": 0
}, },
"Misconfigurations": [ "Misconfigurations": [
{ {
"Type": "Dockerfile Security Check", "Type": "Dockerfile Security Check",
"ID": "DS002", "ID": "DS002",
"AVDID": "AVD-DS-0002",
"Title": "Image user should not be 'root'", "Title": "Image user should not be 'root'",
"Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.", "Description": "Running containers with 'root' user can lead to a container escape situation. It is a best practice to run containers as non-root users, which can be done by adding a 'USER' statement to the Dockerfile.",
"Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument", "Message": "Specify at least 1 USER command in Dockerfile with non-root user as argument",
@@ -49,6 +50,32 @@
"Lines": null "Lines": null
} }
} }
},
{
"Type": "Dockerfile Security Check",
"ID": "DS026",
"AVDID": "AVD-DS-0026",
"Title": "No HEALTHCHECK defined",
"Description": "You shoud add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.",
"Message": "Add HEALTHCHECK instruction in your Dockerfile",
"Namespace": "builtin.dockerfile.DS026",
"Query": "data.builtin.dockerfile.DS026.deny",
"Resolution": "Add HEALTHCHECK instruction in Dockerfile",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/ds026",
"References": [
"https://blog.aquasec.com/docker-security-best-practices",
"https://avd.aquasec.com/misconfig/ds026"
],
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Provider": "Dockerfile",
"Service": "general",
"Code": {
"Lines": null
}
}
} }
] ]
} }
-17
View File
@@ -1,17 +0,0 @@
{
"SchemaVersion": 2,
"ArtifactName": ".",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
}
}
+10 -3337
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+101 -1478
View File
File diff suppressed because it is too large Load Diff
+44 -1
View File
@@ -26,7 +26,50 @@
"Title": "GitHub Personal Access Token", "Title": "GitHub Personal Access Token",
"StartLine": 5, "StartLine": 5,
"EndLine": 5, "EndLine": 5,
"Match": "export GITHUB_PAT=*****" "Code": {
"Lines": [
{
"Number": 3,
"Content": "export AWS_ACCESS_KEY_ID=1234567",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"Highlighted": "export AWS_ACCESS_KEY_ID=1234567",
"FirstCause": false,
"LastCause": false
},
{
"Number": 4,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
},
{
"Number": 5,
"Content": "export GITHUB_PAT=****************************************",
"IsCause": true,
"Annotation": "",
"Truncated": false,
"Highlighted": "export GITHUB_PAT=****************************************",
"FirstCause": true,
"LastCause": true
},
{
"Number": 6,
"Content": "",
"IsCause": false,
"Annotation": "",
"Truncated": false,
"FirstCause": false,
"LastCause": false
}
]
},
"Match": "export GITHUB_PAT=****************************************",
"Layer": {}
} }
] ]
} }
-17
View File
@@ -1,17 +0,0 @@
{
"SchemaVersion": 2,
"ArtifactName": ".",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
}
}
+5
View File
@@ -0,0 +1,5 @@
format: json
severity: CRITICAL
vulnerability:
type: os
output: yamlconfig.test
+105
View File
@@ -0,0 +1,105 @@
{
"SchemaVersion": 2,
"ArtifactName": "alpine:3.10",
"ArtifactType": "container_image",
"Metadata": {
"OS": {
"Family": "alpine",
"Name": "3.10.9",
"EOSL": true
},
"ImageID": "sha256:e7b300aee9f9bf3433d32bc9305bfdd22183beb59d933b48d77ab56ba53a197a",
"DiffIDs": [
"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
],
"RepoTags": [
"alpine:3.10"
],
"RepoDigests": [
"alpine@sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98"
],
"ImageConfig": {
"architecture": "amd64",
"container": "fdb7e80e3339e8d0599282e606c907aa5881ee4c668a68136119e6dfac6ce3a4",
"created": "2021-04-14T19:20:05.338397761Z",
"docker_version": "19.03.12",
"history": [
{
"created": "2021-04-14T19:20:04.987219124Z",
"created_by": "/bin/sh -c #(nop) ADD file:c5377eaa926bf412dd8d4a08b0a1f2399cfd708743533b0aa03b53d14cb4bb4e in / "
},
{
"created": "2021-04-14T19:20:05.338397761Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
]
},
"config": {
"Cmd": [
"/bin/sh"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Image": "sha256:eb2080c455e94c22ae35b3aef9e078c492a00795412e026e4d6b41ef64bc7dd8"
}
}
},
"Results": [
{
"Target": "alpine:3.10 (alpine 3.10.9)",
"Class": "os-pkgs",
"Type": "alpine",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2021-36159",
"PkgID": "apk-tools@2.10.6-r0",
"PkgName": "apk-tools",
"InstalledVersion": "2.10.6-r0",
"FixedVersion": "2.10.7-r0",
"Layer": {
"Digest": "sha256:396c31837116ac290458afcb928f68b6cc1c7bdd6963fc72f52f365a2a89c1b5",
"DiffID": "sha256:9fb3aa2f8b8023a4bebbf92aa567caf88e38e969ada9f0ac12643b2847391635"
},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-36159",
"DataSource": {
"ID": "alpine",
"Name": "Alpine Secdb",
"URL": "https://secdb.alpinelinux.org/"
},
"Description": "libfetch before 2021-07-26, as used in apk-tools, xbps, and other products, mishandles numeric strings for the FTP and HTTP protocols. The FTP passive mode implementation allows an out-of-bounds read because strtol is used to parse the relevant numbers into address bytes. It does not check if the line ends prematurely. If it does, the for-loop condition checks for the '\\0' terminator one byte too late.",
"Severity": "CRITICAL",
"CweIDs": [
"CWE-125"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:L/Au:N/C:P/I:N/A:P",
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H",
"V2Score": 6.4,
"V3Score": 9.1
}
},
"References": [
"https://github.com/freebsd/freebsd-src/commits/main/lib/libfetch",
"https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10749",
"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cdev.kafka.apache.org%3E",
"https://lists.apache.org/thread.html/r61db8e7dcb56dc000a5387a88f7a473bacec5ee01b9ff3f55308aacc@%3Cusers.kafka.apache.org%3E",
"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cdev.kafka.apache.org%3E",
"https://lists.apache.org/thread.html/rbf4ce74b0d1fa9810dec50ba3ace0caeea677af7c27a97111c06ccb7@%3Cusers.kafka.apache.org%3E"
],
"PublishedDate": "2021-08-03T14:15:00Z",
"LastModifiedDate": "2021-10-18T12:19:00Z"
}
]
}
]
}
+54 -36
View File
@@ -1,61 +1,71 @@
#!/usr/bin/env bats #!/usr/bin/env bats
load '/usr/lib/bats-support/load.bash' bats_load_library bats-support
load '/usr/lib/bats-assert/load.bash' bats_load_library bats-assert
bats_load_library bats-file
@test "trivy image" { @test "trivy repo with securityCheck secret only" {
# trivy image --severity CRITICAL --format json --output image.test knqyf263/vuln-image:1.2.3 # trivy repo --format json --output repo.test --security-checks=secret https://github.com/krol3/demo-trivy/
./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-b json' '-h image.test' '-g CRITICAL' run ./entrypoint.sh '-b json' '-h repo.test' '-s secret' '-a repo' '-j https://github.com/krol3/demo-trivy/'
result="$(diff ./test/data/image.test image.test)" run diff repo.test ./test/data/repo.test
[ "$result" == '' ] echo "$output"
assert_files_equal repo.test ./test/data/repo.test
} }
@test "trivy image sarif report" { @test "trivy image" {
# trivy image --severity CRITICAL -f sarif --output image-sarif.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 sarif' '-h image-sarif.test' '-g CRITICAL' run ./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-h image.test' '-g CRITICAL'
result="$(diff ./test/data/image-sarif.test image-sarif.test)" run diff image.test ./test/data/image.test
[ "$result" == '' ] echo "$output"
assert_files_equal image.test ./test/data/image.test
}
@test "trivy config sarif report" {
# trivy config --format sarif --output config-sarif.test .
run ./entrypoint.sh '-a config' '-b sarif' '-h config-sarif.test' '-j .'
run diff config-sarif.test ./test/data/config-sarif.test
echo "$output"
assert_files_equal config-sarif.test ./test/data/config-sarif.test
} }
@test "trivy config" { @test "trivy config" {
# trivy config --format json --output config.test . # trivy config --format json --output config.test .
./entrypoint.sh '-a config' '-j .' '-b json' '-h config.test' run ./entrypoint.sh '-a config' '-b json' '-j .' '-h config.test'
result="$(diff ./test/data/config.test config.test)" run diff config.test ./test/data/config.test
[ "$result" == '' ] echo "$output"
assert_files_equal config.test ./test/data/config.test
} }
@test "trivy rootfs" { @test "trivy rootfs" {
# trivy rootfs --format json --output rootfs.test . # trivy rootfs --output rootfs.test .
./entrypoint.sh '-a rootfs' '-j .' '-b json' '-h rootfs.test' run ./entrypoint.sh '-a rootfs' '-j .' '-h rootfs.test'
result="$(diff ./test/data/rootfs.test rootfs.test)" run diff rootfs.test ./test/data/rootfs.test
[ "$result" == '' ] echo "$output"
assert_files_equal rootfs.test ./test/data/rootfs.test
} }
@test "trivy fs" { @test "trivy fs" {
# trivy fs --format json --output fs.test . # trivy fs --output fs.test .
./entrypoint.sh '-a fs' '-j .' '-b json' '-h fs.test' run ./entrypoint.sh '-a fs' '-j .' '-h fs.test'
result="$(diff ./test/data/fs.test fs.test)" run diff fs.test ./test/data/fs.test
[ "$result" == '' ] echo "$output"
assert_files_equal fs.test ./test/data/fs.test
} }
@test "trivy fs with securityChecks option" { @test "trivy fs with securityChecks option" {
# trivy fs --format json --security-checks=vuln,config --output fs-scheck.test . # trivy fs --format json --security-checks=vuln,config --output fs-scheck.test .
./entrypoint.sh '-a fs' '-j .' '-b json' '-s vuln,config,secret' '-h fs-scheck.test' run ./entrypoint.sh '-a fs' '-b json' '-j .' '-s vuln,config,secret' '-h fs-scheck.test'
result="$(diff ./test/data/fs-scheck.test fs-scheck.test)" run diff fs-scheck.test ./test/data/fs-scheck.test
[ "$result" == '' ] echo "$output"
assert_files_equal fs-scheck.test ./test/data/fs-scheck.test
} }
@test "trivy repo with securityCheck secret only" {
# trivy repo --format 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" == '' ]
}
@test "trivy image with trivyIgnores option" { @test "trivy image with trivyIgnores option" {
# cat ./test/data/.trivyignore1 ./test/data/.trivyignore2 > ./trivyignores ; trivy image --severity CRITICAL --format json --output image-trivyignores.test --ignorefile ./trivyignores knqyf263/vuln-image:1.2.3 # 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 json' '-h image-trivyignores.test' '-g CRITICAL' '-t ./test/data/.trivyignore1,./test/data/.trivyignore2' run ./entrypoint.sh '-a image' '-i knqyf263/vuln-image:1.2.3' '-h image-trivyignores.test' '-g CRITICAL' '-t ./test/data/.trivyignore1,./test/data/.trivyignore2'
result="$(diff ./test/data/image-trivyignores.test image-trivyignores.test)" run diff image-trivyignores.test ./test/data/image-trivyignores.test
[ "$result" == '' ] echo "$output"
assert_files_equal image-trivyignores.test ./test/data/image-trivyignores.test
} }
@test "trivy image with sbom output" { @test "trivy image with sbom output" {
@@ -63,3 +73,11 @@ load '/usr/lib/bats-assert/load.bash'
run ./entrypoint.sh "-a image" "-b github" "-i knqyf263/vuln-image:1.2.3" run ./entrypoint.sh "-a image" "-b github" "-i knqyf263/vuln-image:1.2.3"
assert_output --partial '"package_url": "pkg:apk/ca-certificates@20171114-r0",' # TODO: Output contains time, need to mock assert_output --partial '"package_url": "pkg:apk/ca-certificates@20171114-r0",' # TODO: Output contains time, need to mock
} }
@test "trivy image with trivy.yaml config" {
# trivy --config=./test/data/trivy.yaml image alpine:3.10
run ./entrypoint.sh "-v ./test/data/trivy.yaml" "-a image" "-i alpine:3.10"
run diff yamlconfig.test ./test/data/yamlconfig.test
echo "$output"
assert_files_equal yamlconfig.test ./test/data/yamlconfig.test
}
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-18.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2