mirror of
https://github.com/aquasecurity/trivy-action.git
synced 2026-05-14 03:02:40 +00:00
feat: support for YAML ignore file
Signed-off-by: Nikita Pivkin <nikita.pivkin@smartforce.io>
This commit is contained in:
@@ -5,3 +5,6 @@ trivyignores
|
||||
.vscode/
|
||||
|
||||
.cache
|
||||
|
||||
# Local tools
|
||||
.bin/
|
||||
|
||||
@@ -8,30 +8,65 @@ else
|
||||
BATS_LIB_PATH ?= /usr/local/lib/
|
||||
endif
|
||||
|
||||
LOCAL_BIN := $(CURDIR)/.bin
|
||||
LOCAL_TRIVY := $(LOCAL_BIN)/trivy
|
||||
|
||||
ifeq ($(shell [ -f $(LOCAL_TRIVY) ] && [ -z "$(CI)" ] && echo yes),yes)
|
||||
TRIVY_CMD := $(LOCAL_TRIVY)
|
||||
else
|
||||
TRIVY_CMD ?= trivy
|
||||
endif
|
||||
|
||||
CACHE_DIR := '.cache'
|
||||
|
||||
TRIVY_VERSION_FILE := .github/workflows/test.yaml
|
||||
CURRENT_TRIVY_VERSION := $(shell awk '/TRIVY_VERSION:/ {print $$2}' $(TRIVY_VERSION_FILE))
|
||||
|
||||
BATS_ENV := BATS_LIB_PATH=$(BATS_LIB_PATH) \
|
||||
GITHUB_REPOSITORY_OWNER=aquasecurity \
|
||||
TRIVY_CACHE_DIR=.cache \
|
||||
TRIVY_DISABLE_VEX_NOTICE=true \
|
||||
TRIVY_CACHE_DIR=$(CACHE_DIR) \
|
||||
TRIVY_DEBUG=true
|
||||
|
||||
BATS_FLAGS := --recursive --timing --verbose-run .
|
||||
BATS_FLAGS := --timing --verbose-run test/test.bats
|
||||
|
||||
.PHONY: test
|
||||
test: init-cache
|
||||
$(BATS_ENV) bats $(BATS_FLAGS)
|
||||
test:
|
||||
TRIVY_CMD=$(TRIVY_CMD) $(BATS_ENV) bats $(BATS_FLAGS)
|
||||
|
||||
.PHONY: update-golden
|
||||
update-golden: init-cache
|
||||
UPDATE_GOLDEN=1 $(BATS_ENV) bats $(BATS_FLAGS)
|
||||
update-golden:
|
||||
UPDATE_GOLDEN=1 TRIVY_CMD=$(TRIVY_CMD) $(BATS_ENV) bats $(BATS_FLAGS)
|
||||
|
||||
.PHONY: init-cache
|
||||
init-cache:
|
||||
mkdir -p .cache
|
||||
rm -f .cache/fanal/fanal.db
|
||||
mkdir -p $(CACHE_DIR)
|
||||
|
||||
.PHONY: clean-cache
|
||||
clean-cache:
|
||||
$(TRIVY_CMD) clean --scan-cache --cache-dir $(CACHE_DIR)
|
||||
|
||||
bump-trivy:
|
||||
@[ $$NEW_VERSION ] || ( echo "env 'NEW_VERSION' is not set"; exit 1 )
|
||||
@CURRENT_VERSION=$$(grep "TRIVY_VERSION:" .github/workflows/test.yaml | awk '{print $$2}');\
|
||||
echo Current version: $$CURRENT_VERSION ;\
|
||||
@echo Current version: $(CURRENT_TRIVY_VERSION) ;\
|
||||
echo New version: $$NEW_VERSION ;\
|
||||
$(SED) -i -e "s/$$CURRENT_VERSION/$$NEW_VERSION/g" README.md action.yaml .github/workflows/test.yaml ;\
|
||||
$(SED) -i -e "s/$(CURRENT_TRIVY_VERSION)/$$NEW_VERSION/g" \
|
||||
README.md action.yaml $(TRIVY_VERSION_FILE)
|
||||
|
||||
.PHONY: ensure-trivy
|
||||
ensure-trivy:
|
||||
@set -e; \
|
||||
mkdir -p $(LOCAL_BIN); \
|
||||
if [ -x $(LOCAL_TRIVY) ]; then \
|
||||
CURRENT_VERSION="$$( $(LOCAL_TRIVY) version -f json | jq -r '.Version' )"; \
|
||||
else \
|
||||
CURRENT_VERSION=none; \
|
||||
fi; \
|
||||
echo "Required: $(CURRENT_TRIVY_VERSION)"; \
|
||||
echo "Current: $$CURRENT_VERSION"; \
|
||||
if [ "$$CURRENT_VERSION" != "$(CURRENT_TRIVY_VERSION)" ]; then \
|
||||
echo "Installing Trivy $(CURRENT_TRIVY_VERSION) locally..."; \
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | \
|
||||
sh -s -- -b $(LOCAL_BIN) v$(CURRENT_TRIVY_VERSION); \
|
||||
else \
|
||||
echo "Trivy $(CURRENT_TRIVY_VERSION) already present."; \
|
||||
fi
|
||||
@@ -886,7 +886,7 @@ Following inputs can be used as `step.with` keys:
|
||||
| `hide-progress` | String | `false` | Suppress progress bar and log output |
|
||||
| `list-all-pkgs` | String | | Output all packages regardless of vulnerability |
|
||||
| `scanners` | String | `vuln,secret` | comma-separated list of what security issues to detect (`vuln`,`secret`,`misconfig`,`license`) |
|
||||
| `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` or `.trivyignore.yaml` files. |
|
||||
| `trivy-config` | String | | Path to trivy.yaml config |
|
||||
| `github-pat` | String | | Authentication token to enable sending SBOM scan results to GitHub Dependency Graph. Can be either a GitHub Personal Access Token (PAT) or GITHUB_TOKEN |
|
||||
| `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** |
|
||||
|
||||
+45
-9
@@ -1,6 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Allow overriding trivy binary via env
|
||||
TRIVY_CMD="${TRIVY_CMD:-trivy}"
|
||||
|
||||
# Read TRIVY_* envs from file, previously they were written to the GITHUB_ENV file but GitHub Actions automatically
|
||||
# injects those into subsequent job steps which means inputs from one trivy-action invocation were leaking over to
|
||||
# any subsequent invocation which led to unexpected/undesireable behaviour from a user perspective
|
||||
@@ -18,23 +21,56 @@ fi
|
||||
|
||||
# Handle trivy ignores
|
||||
if [ -n "${INPUT_TRIVYIGNORES:-}" ]; then
|
||||
ignorefile="./trivyignores"
|
||||
|
||||
# Clear the ignore file if it exists, or create a new empty file
|
||||
: > "$ignorefile"
|
||||
yaml_count=0
|
||||
plain_count=0
|
||||
|
||||
# Validate files and detect types
|
||||
for f in ${INPUT_TRIVYIGNORES//,/ }; do
|
||||
if [ -f "$f" ]; then
|
||||
echo "Found ignorefile '${f}':"
|
||||
cat "${f}"
|
||||
cat "${f}" >> "$ignorefile"
|
||||
else
|
||||
if [ ! -f "$f" ]; then
|
||||
echo "ERROR: cannot find ignorefile '${f}'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$f" in
|
||||
*.yml|*.yaml) yaml_count=$((yaml_count + 1)) ;;
|
||||
*) plain_count=$((plain_count + 1)) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Mixed types are not allowed
|
||||
if [ "$yaml_count" -gt 0 ] && [ "$plain_count" -gt 0 ]; then
|
||||
echo "ERROR: Cannot mix YAML and plain trivy ignore files." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# YAML mode
|
||||
if [ "$yaml_count" -gt 0 ]; then
|
||||
if [ "$yaml_count" -gt 1 ]; then
|
||||
echo "ERROR: Multiple YAML ignore files provided. Only one YAML file is supported." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use the single YAML file
|
||||
yaml_file=$(echo ${INPUT_TRIVYIGNORES//,/ } | awk '{print $1}')
|
||||
echo "Using YAML ignorefile '$yaml_file':"
|
||||
cat "$yaml_file"
|
||||
export TRIVY_IGNOREFILE="$yaml_file"
|
||||
|
||||
else
|
||||
# Plain mode (old behaviour)
|
||||
ignorefile="./trivyignores"
|
||||
: > "$ignorefile"
|
||||
|
||||
for f in ${INPUT_TRIVYIGNORES//,/ }; do
|
||||
echo "Found ignorefile '$f':"
|
||||
cat "$f"
|
||||
cat "$f" >> "$ignorefile"
|
||||
done
|
||||
|
||||
export TRIVY_IGNOREFILE="$ignorefile"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle SARIF
|
||||
if [ "${TRIVY_FORMAT:-}" = "sarif" ]; then
|
||||
@@ -47,7 +83,7 @@ if [ "${TRIVY_FORMAT:-}" = "sarif" ]; then
|
||||
fi
|
||||
|
||||
# Run Trivy
|
||||
cmd=(trivy "$scanType" "$scanRef")
|
||||
cmd=("$TRIVY_CMD" "$scanType" "$scanRef")
|
||||
echo "Running Trivy with options: ${cmd[*]}"
|
||||
"${cmd[@]}"
|
||||
returnCode=$?
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
format: json
|
||||
severity: CRITICAL
|
||||
vulnerability:
|
||||
type: os
|
||||
output: yamlconfig.json
|
||||
@@ -0,0 +1,3 @@
|
||||
vulnerabilities:
|
||||
- id: CVE-2018-14618
|
||||
- id: CVE-2018-16839
|
||||
@@ -0,0 +1,102 @@
|
||||
|
||||
Report Summary
|
||||
|
||||
┌──────────────────────────────────────────┬────────┬─────────────────┬─────────┐
|
||||
│ Target │ Type │ Vulnerabilities │ Secrets │
|
||||
├──────────────────────────────────────────┼────────┼─────────────────┼─────────┤
|
||||
│ knqyf263/vuln-image:1.2.3 (alpine 3.7.1) │ alpine │ 16 │ - │
|
||||
├──────────────────────────────────────────┼────────┼─────────────────┼─────────┤
|
||||
│ rust-app/Cargo.lock │ cargo │ 4 │ - │
|
||||
└──────────────────────────────────────────┴────────┴─────────────────┴─────────┘
|
||||
Legend:
|
||||
- '-': Not scanned
|
||||
- '0': Clean (no security findings detected)
|
||||
|
||||
|
||||
knqyf263/vuln-image:1.2.3 (alpine 3.7.1)
|
||||
========================================
|
||||
Total: 16 (CRITICAL: 16)
|
||||
|
||||
┌─────────────┬────────────────┬──────────┬────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
|
||||
│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │
|
||||
├─────────────┼────────────────┼──────────┼────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ curl │ CVE-2018-16840 │ CRITICAL │ fixed │ 7.61.0-r0 │ 7.61.1-r1 │ curl: Use-after-free when closing "easy" handle in │
|
||||
│ │ │ │ │ │ │ Curl_close() │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-16840 │
|
||||
│ ├────────────────┤ │ │ │ ├──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2018-16842 │ │ │ │ │ curl: Heap-based buffer over-read in the curl tool warning │
|
||||
│ │ │ │ │ │ │ formatting │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-16842 │
|
||||
│ ├────────────────┤ │ │ ├───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-3822 │ │ │ │ 7.61.1-r2 │ curl: NTLMv2 type-3 header stack buffer overflow │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-3822 │
|
||||
│ ├────────────────┤ │ │ ├───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-5481 │ │ │ │ 7.61.1-r3 │ curl: double free due to subsequent call of realloc() │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-5481 │
|
||||
│ ├────────────────┤ │ │ │ ├──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-5482 │ │ │ │ │ curl: heap buffer overflow in function tftp_receive_packet() │
|
||||
│ │ │ │ │ │ │ https://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 │
|
||||
│ │ │ │ │ │ │ https://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... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-1353 │
|
||||
├─────────────┼────────────────┤ │ ├───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ libbz2 │ CVE-2019-12900 │ │ │ 1.0.6-r6 │ 1.0.6-r7 │ bzip2: bzip2: Data integrity error when decompressing (with │
|
||||
│ │ │ │ │ │ │ data integrity tests fail).... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-12900 │
|
||||
├─────────────┼────────────────┤ │ ├───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ libcurl │ CVE-2018-16840 │ │ │ 7.61.1-r0 │ 7.61.1-r1 │ curl: Use-after-free when closing "easy" handle in │
|
||||
│ │ │ │ │ │ │ Curl_close() │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-16840 │
|
||||
│ ├────────────────┤ │ │ │ ├──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2018-16842 │ │ │ │ │ curl: Heap-based buffer over-read in the curl tool warning │
|
||||
│ │ │ │ │ │ │ formatting │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2018-16842 │
|
||||
│ ├────────────────┤ │ │ ├───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-3822 │ │ │ │ 7.61.1-r2 │ curl: NTLMv2 type-3 header stack buffer overflow │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-3822 │
|
||||
│ ├────────────────┤ │ │ ├───────────────┼──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-5481 │ │ │ │ 7.61.1-r3 │ curl: double free due to subsequent call of realloc() │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-5481 │
|
||||
│ ├────────────────┤ │ │ │ ├──────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-5482 │ │ │ │ │ curl: heap buffer overflow in function tftp_receive_packet() │
|
||||
│ │ │ │ │ │ │ https://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 ...... │
|
||||
│ │ │ │ │ │ │ https://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() │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-8457 │
|
||||
└─────────────┴────────────────┴──────────┴────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────────┘
|
||||
|
||||
rust-app/Cargo.lock (cargo)
|
||||
===========================
|
||||
Total: 4 (CRITICAL: 4)
|
||||
|
||||
┌───────────┬────────────────┬──────────┬────────┬───────────────────┬───────────────┬─────────────────────────────────────────────────────────────┐
|
||||
│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │
|
||||
├───────────┼────────────────┼──────────┼────────┼───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
|
||||
│ rand_core │ CVE-2020-25576 │ CRITICAL │ fixed │ 0.4.0 │ 0.4.2, 0.3.1 │ An issue was discovered in the rand_core crate before 0.4.2 │
|
||||
│ │ │ │ │ │ │ for Rust.... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2020-25576 │
|
||||
├───────────┼────────────────┤ │ ├───────────────────┼───────────────┼─────────────────────────────────────────────────────────────┤
|
||||
│ smallvec │ CVE-2019-15551 │ │ │ 0.6.9 │ 0.6.10 │ An issue was discovered in the smallvec crate before 0.6.10 │
|
||||
│ │ │ │ │ │ │ for Rust.... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-15551 │
|
||||
│ ├────────────────┤ │ │ │ ├─────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2019-15554 │ │ │ │ │ An issue was discovered in the smallvec crate before 0.6.10 │
|
||||
│ │ │ │ │ │ │ for Rust.... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2019-15554 │
|
||||
│ ├────────────────┤ │ │ ├───────────────┼─────────────────────────────────────────────────────────────┤
|
||||
│ │ CVE-2021-25900 │ │ │ │ 0.6.14, 1.6.1 │ An issue was discovered in the smallvec crate before 0.6.14 │
|
||||
│ │ │ │ │ │ │ and 1.x... │
|
||||
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2021-25900 │
|
||||
└───────────┴────────────────┴──────────┴────────┴───────────────────┴───────────────┴─────────────────────────────────────────────────────────────┘
|
||||
+180
-93
@@ -1,41 +1,39 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
setup_file() {
|
||||
local owner=$GITHUB_REPOSITORY_OWNER
|
||||
export TRIVY_DB_REPOSITORY=ghcr.io/${owner}/trivy-db-act:latest
|
||||
export TRIVY_JAVA_DB_REPOSITORY=ghcr.io/${owner}/trivy-java-db-act:latest
|
||||
export TRIVY_CHECKS_BUNDLE_REPOSITORY=ghcr.io/${owner}/trivy-checks-act:latest
|
||||
export TRIVY_LIST_ALL_PKGS=false
|
||||
}
|
||||
|
||||
setup() {
|
||||
bats_load_library bats-support
|
||||
bats_load_library bats-assert
|
||||
bats_load_library bats-file
|
||||
|
||||
setup_file() {
|
||||
setup_trivy_env
|
||||
docker pull knqyf263/vuln-image:1.2.3 1>&3 2>&3
|
||||
trivy image --download-db-only 1>&3 2>&3
|
||||
}
|
||||
|
||||
function remove_json_fields() {
|
||||
local file="$1"
|
||||
if [[ "$file" == *.json ]]; then
|
||||
jq 'del(.CreatedAt, .ReportID)' "$file" > tmp && mv tmp "$file"
|
||||
fi
|
||||
setup() {
|
||||
export TRIVY_OUTPUT="$BATS_TEST_TMPDIR/output.test"
|
||||
export TRIVY_SKIP_DB_UPDATE=true
|
||||
export TRIVY_SKIP_JAVA_DB_UPDATE=true
|
||||
}
|
||||
|
||||
function remove_sarif_fields() {
|
||||
local file="$1"
|
||||
if [[ "$file" == *.sarif ]]; then
|
||||
jq 'del(.runs[].tool.driver.version) | del(.runs[].originalUriBaseIds)' "$file" > tmp && mv tmp "$file"
|
||||
fi
|
||||
teardown() {
|
||||
reset_envs
|
||||
}
|
||||
|
||||
function remove_github_fields() {
|
||||
local file="$1"
|
||||
if [[ "$file" == *.gsbom ]]; then
|
||||
jq 'del(.detector.version) | del(.scanned) | del(.job) | del(.ref) | del(.sha)' "$file" > tmp && mv tmp "$file"
|
||||
fi
|
||||
setup_trivy_env() {
|
||||
local owner="${GITHUB_REPOSITORY_OWNER:-aquasecurity}"
|
||||
|
||||
export TRIVY_DB_REPOSITORY="ghcr.io/${owner}/trivy-db-act:latest"
|
||||
export TRIVY_JAVA_DB_REPOSITORY="ghcr.io/${owner}/trivy-java-db-act:latest"
|
||||
export TRIVY_CHECKS_BUNDLE_REPOSITORY="ghcr.io/${owner}/trivy-checks-act:latest"
|
||||
|
||||
export TRIVY_LIST_ALL_PKGS=false
|
||||
export TRIVY_DISABLE_VEX_NOTICE=true
|
||||
export TRIVY_SKIP_VERSION_CHECK=true
|
||||
export TRIVY_DISABLE_TELEMETRY=true
|
||||
}
|
||||
|
||||
function reset_envs() {
|
||||
reset_envs() {
|
||||
local var
|
||||
for var in $(env | grep '^TRIVY_\|^INPUT_' | cut -d= -f1); do
|
||||
unset "$var"
|
||||
@@ -43,133 +41,161 @@ function reset_envs() {
|
||||
rm -f trivy_envs.txt
|
||||
}
|
||||
|
||||
function compare_files() {
|
||||
local file1="$1"
|
||||
local file2="$2"
|
||||
compare_files() {
|
||||
local actual="$1"
|
||||
local expected="$2"
|
||||
|
||||
# Some fields should be removed as they are environment dependent
|
||||
# and may cause undesirable results when comparing files.
|
||||
remove_json_fields "$file1"
|
||||
remove_json_fields "$file2"
|
||||
|
||||
remove_sarif_fields "$file1"
|
||||
remove_sarif_fields "$file2"
|
||||
|
||||
remove_github_fields "$file1"
|
||||
remove_github_fields "$file2"
|
||||
normalize_report "$actual"
|
||||
normalize_report "$expected"
|
||||
|
||||
if [ "${UPDATE_GOLDEN}" = "1" ]; then
|
||||
cp "$file1" "$file2"
|
||||
echo "Updated golden file: $file2"
|
||||
cp "$actual" "$expected"
|
||||
echo "Updated golden file: $expected"
|
||||
else
|
||||
run diff "$file1" "$file2"
|
||||
run diff "$actual" "$expected"
|
||||
echo "$output"
|
||||
assert_files_equal "$file1" "$file2"
|
||||
assert_files_equal "$actual" "$expected"
|
||||
fi
|
||||
|
||||
rm -f "$file1"
|
||||
rm -f "$actual"
|
||||
}
|
||||
|
||||
|
||||
normalize_report() {
|
||||
local file="$1"
|
||||
|
||||
case "$TRIVY_FORMAT" in
|
||||
json)
|
||||
apply_jq_filter "$file" \
|
||||
'del(.CreatedAt, .ReportID)'
|
||||
;;
|
||||
sarif)
|
||||
apply_jq_filter "$file" \
|
||||
'del(.runs[].tool.driver.version)
|
||||
| del(.runs[].originalUriBaseIds)'
|
||||
;;
|
||||
github)
|
||||
apply_jq_filter "$file" \
|
||||
'del(.detector.version)
|
||||
| del(.scanned)
|
||||
| del(.job)
|
||||
| del(.ref)
|
||||
| del(.sha)'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
apply_jq_filter() {
|
||||
local file="$1"
|
||||
local filter="$2"
|
||||
local tmp="$BATS_TEST_TMPDIR/jq.tmp"
|
||||
|
||||
jq "$filter" "$file" > "$tmp" && mv "$tmp" "$file"
|
||||
}
|
||||
|
||||
run_test_case_compare() {
|
||||
local expected_file="$1"
|
||||
|
||||
run ./entrypoint.sh
|
||||
assert_success
|
||||
|
||||
compare_files "$TRIVY_OUTPUT" "$expected_file"
|
||||
}
|
||||
|
||||
run_test_case_fails() {
|
||||
local expected_msg="$1"
|
||||
|
||||
run ./entrypoint.sh
|
||||
assert_failure
|
||||
|
||||
if [ -n "$expected_msg" ]; then
|
||||
assert_output --partial "$expected_msg"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "trivy repo with securityCheck secret only" {
|
||||
# trivy repo -f json -o repo.test --scanners=secret https://github.com/krol3/demo-trivy/
|
||||
export TRIVY_FORMAT=json TRIVY_OUTPUT=repo.json TRIVY_SCANNERS=secret INPUT_SCAN_TYPE=repo INPUT_SCAN_REF="https://github.com/krol3/demo-trivy/"
|
||||
./entrypoint.sh
|
||||
compare_files repo.json ./test/data/secret-scan/report.json
|
||||
reset_envs
|
||||
export TRIVY_FORMAT=json TRIVY_SCANNERS=secret INPUT_SCAN_TYPE=repo INPUT_SCAN_REF="https://github.com/krol3/demo-trivy/"
|
||||
run_test_case_compare ./test/data/secret-scan/report.json
|
||||
}
|
||||
|
||||
@test "trivy image" {
|
||||
# trivy image --severity CRITICAL -o image.test knqyf263/vuln-image:1.2.3
|
||||
export TRIVY_OUTPUT=image.test TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3
|
||||
./entrypoint.sh
|
||||
compare_files image.test ./test/data/image-scan/report
|
||||
reset_envs
|
||||
export TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3
|
||||
run_test_case_compare ./test/data/image-scan/report
|
||||
}
|
||||
|
||||
@test "trivy config sarif report" {
|
||||
# trivy config -f sarif -o config-sarif.test ./test/data/config-sarif-report
|
||||
export TRIVY_FORMAT=sarif TRIVY_OUTPUT=config-sarif.sarif INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/config-sarif-report
|
||||
./entrypoint.sh
|
||||
compare_files config-sarif.sarif ./test/data/config-sarif-report/report.sarif
|
||||
reset_envs
|
||||
export TRIVY_FORMAT=sarif INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/config-sarif-report
|
||||
run_test_case_compare ./test/data/config-sarif-report/report.sarif
|
||||
}
|
||||
|
||||
@test "trivy config" {
|
||||
# trivy config -f json -o config.json ./test/data/config-scan
|
||||
export TRIVY_FORMAT=json TRIVY_OUTPUT=config.json INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/config-scan
|
||||
./entrypoint.sh
|
||||
compare_files config.json ./test/data/config-scan/report.json
|
||||
reset_envs
|
||||
export TRIVY_FORMAT=json INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/config-scan
|
||||
run_test_case_compare ./test/data/config-scan/report.json
|
||||
}
|
||||
|
||||
@test "trivy rootfs" {
|
||||
# trivy rootfs --output rootfs.test ./test/data/rootfs-scan
|
||||
# TODO: add data
|
||||
export TRIVY_OUTPUT=rootfs.test INPUT_SCAN_TYPE=rootfs INPUT_SCAN_REF=./test/data/rootfs-scan
|
||||
./entrypoint.sh
|
||||
compare_files rootfs.test ./test/data/rootfs-scan/report
|
||||
reset_envs
|
||||
export INPUT_SCAN_TYPE=rootfs INPUT_SCAN_REF=./test/data/rootfs-scan
|
||||
run_test_case_compare ./test/data/rootfs-scan/report
|
||||
}
|
||||
|
||||
@test "trivy fs" {
|
||||
# trivy fs --output fs.test ./test/data/fs-scan
|
||||
# TODO: add data
|
||||
export TRIVY_OUTPUT=fs.test INPUT_SCAN_TYPE=fs INPUT_SCAN_REF=./test/data/fs-scan
|
||||
./entrypoint.sh
|
||||
compare_files fs.test ./test/data/fs-scan/report
|
||||
reset_envs
|
||||
export INPUT_SCAN_TYPE=fs INPUT_SCAN_REF=./test/data/fs-scan
|
||||
run_test_case_compare ./test/data/fs-scan/report
|
||||
}
|
||||
|
||||
@test "trivy image with trivyIgnores option" {
|
||||
# cat ./test/data/with-ignore-files/.trivyignore1 ./test/data/with-ignore-files/.trivyignore2 > ./trivyignores ; trivy image --severity CRITICAL --output image-trivyignores.test --ignorefile ./trivyignores knqyf263/vuln-image:1.2.3
|
||||
export TRIVY_OUTPUT=image-trivyignores.test TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_IMAGE_REF=knqyf263/vuln-image:1.2.3 INPUT_TRIVYIGNORES="./test/data/with-ignore-files/.trivyignore1,./test/data/with-ignore-files/.trivyignore2"
|
||||
./entrypoint.sh
|
||||
compare_files image-trivyignores.test ./test/data/with-ignore-files/report
|
||||
reset_envs
|
||||
export TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_IMAGE_REF=knqyf263/vuln-image:1.2.3 INPUT_TRIVYIGNORES="./test/data/with-ignore-files/.trivyignore1,./test/data/with-ignore-files/.trivyignore2"
|
||||
run_test_case_compare ./test/data/with-ignore-files/report
|
||||
}
|
||||
|
||||
@test "trivy image with .trivyignore.yaml" {
|
||||
# trivy image --severity CRITICAL --output with-yaml-ignore-file.test --ignorefile ./test/data/with-yaml-ignore-file/.trivyignore.yaml
|
||||
export TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_IMAGE_REF=knqyf263/vuln-image:1.2.3 INPUT_TRIVYIGNORES=./test/data/with-yaml-ignore-file/.trivyignore.yaml
|
||||
run_test_case_compare ./test/data/with-yaml-ignore-file/report
|
||||
}
|
||||
|
||||
@test "trivy image with sbom output" {
|
||||
# trivy image --format github knqyf263/vuln-image:1.2.3
|
||||
export TRIVY_FORMAT=github TRIVY_OUTPUT=github-dep-snapshot.gsbom INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3
|
||||
./entrypoint.sh
|
||||
compare_files github-dep-snapshot.gsbom ./test/data/github-dep-snapshot/report.gsbom
|
||||
reset_envs
|
||||
export TRIVY_FORMAT=github INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3
|
||||
run_test_case_compare ./test/data/github-dep-snapshot/report.gsbom
|
||||
}
|
||||
|
||||
@test "trivy image with trivy.yaml config" {
|
||||
# trivy --config=./test/data/with-trivy-yaml-cfg/trivy.yaml image alpine:3.10
|
||||
export TRIVY_CONFIG=./test/data/with-trivy-yaml-cfg/trivy.yaml INPUT_SCAN_TYPE=image INPUT_SCAN_REF=alpine:3.10
|
||||
./entrypoint.sh
|
||||
compare_files yamlconfig.json ./test/data/with-trivy-yaml-cfg/report.json
|
||||
reset_envs
|
||||
export TRIVY_CONFIG=./test/data/with-trivy-yaml-cfg/trivy.yaml TRIVY_FORMAT=json INPUT_SCAN_TYPE=image INPUT_SCAN_REF=alpine:3.10
|
||||
run_test_case_compare ./test/data/with-trivy-yaml-cfg/report.json
|
||||
}
|
||||
|
||||
@test "trivy image with custom docker-host" {
|
||||
# trivy image --docker-host unix:///var/run/docker.sock --severity CRITICAL --output image.test knqyf263/vuln-image:1.2.3
|
||||
export TRIVY_OUTPUT=image.test TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3 TRIVY_DOCKER_HOST=unix:///var/run/docker.sock
|
||||
./entrypoint.sh
|
||||
compare_files image.test ./test/data/image-scan/report
|
||||
reset_envs
|
||||
export TRIVY_SEVERITY=CRITICAL INPUT_SCAN_TYPE=image INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3 TRIVY_DOCKER_HOST=unix:///var/run/docker.sock
|
||||
run_test_case_compare ./test/data/image-scan/report
|
||||
}
|
||||
|
||||
@test "trivy config with terraform variables" {
|
||||
# trivy config -f json -o tfvars.json --severity MEDIUM --tf-vars ./test/data/with-tf-vars/dev.tfvars ./test/data/with-tf-vars/main.tf
|
||||
export TRIVY_FORMAT=json TRIVY_SEVERITY=MEDIUM TRIVY_OUTPUT=tfvars.json INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/with-tf-vars/main.tf TRIVY_TF_VARS=./test/data/with-tf-vars/dev.tfvars
|
||||
./entrypoint.sh
|
||||
compare_files tfvars.json ./test/data/with-tf-vars/report.json
|
||||
reset_envs
|
||||
export TRIVY_FORMAT=json TRIVY_SEVERITY=MEDIUM INPUT_SCAN_TYPE=config INPUT_SCAN_REF=./test/data/with-tf-vars/main.tf TRIVY_TF_VARS=./test/data/with-tf-vars/dev.tfvars
|
||||
run_test_case_compare ./test/data/with-tf-vars/report.json
|
||||
}
|
||||
|
||||
@test "trivy image via environment file" {
|
||||
# trivy image --severity CRITICAL --output image.test knqyf263/vuln-image:1.2.3
|
||||
# Action injects inputs into the script via environment variables
|
||||
echo "export TRIVY_OUTPUT=image.test" >> trivy_envs.txt
|
||||
echo "export TRIVY_SEVERITY=CRITICAL" >> trivy_envs.txt
|
||||
echo "export INPUT_SCAN_TYPE=image" >> trivy_envs.txt
|
||||
echo "export INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3" >> trivy_envs.txt
|
||||
./entrypoint.sh
|
||||
compare_files image.test ./test/data/image-scan/report
|
||||
reset_envs
|
||||
run_test_case_compare ./test/data/image-scan/report
|
||||
}
|
||||
|
||||
@test "trivy image via environment file overrides env leakages" {
|
||||
@@ -178,11 +204,72 @@ function compare_files() {
|
||||
# If caller mixes old and new trivy-action version they could still have env leakage so verify that env vars already
|
||||
# in the env are overridden by those from the envs file
|
||||
export INPUT_SCAN_REF=no/such-image:1.2.3
|
||||
echo "export TRIVY_OUTPUT=image.test" >> trivy_envs.txt
|
||||
echo "export TRIVY_SEVERITY=CRITICAL" >> trivy_envs.txt
|
||||
echo "export INPUT_SCAN_TYPE=image" >> trivy_envs.txt
|
||||
echo "export INPUT_SCAN_REF=knqyf263/vuln-image:1.2.3" >> trivy_envs.txt
|
||||
./entrypoint.sh
|
||||
compare_files image.test ./test/data/image-scan/report
|
||||
reset_envs
|
||||
run_test_case_compare ./test/data/image-scan/report
|
||||
}
|
||||
|
||||
@test "error if ignorefile does not exist" {
|
||||
missing_file="$BATS_TEST_TMPDIR/missing.ignore"
|
||||
|
||||
export INPUT_TRIVYIGNORES="$missing_file" \
|
||||
INPUT_SCAN_TYPE=fs \
|
||||
INPUT_SCAN_REF=./test/data/fs-scan
|
||||
|
||||
run_test_case_fails "cannot find ignorefile '$missing_file'"
|
||||
}
|
||||
|
||||
@test "error with mixed yaml and plain ignore files" {
|
||||
plain_ignore="$BATS_TEST_TMPDIR/ignore-plain"
|
||||
yaml_ignore="$BATS_TEST_TMPDIR/ignore.yaml"
|
||||
|
||||
touch "$plain_ignore" "$yaml_ignore"
|
||||
|
||||
export INPUT_TRIVYIGNORES="$plain_ignore,$yaml_ignore" \
|
||||
INPUT_SCAN_TYPE=fs \
|
||||
INPUT_SCAN_REF=./test/data/fs-scan
|
||||
|
||||
run_test_case_fails "Cannot mix YAML and plain trivy ignore files"
|
||||
}
|
||||
|
||||
@test "error if multiple YAML files provided" {
|
||||
yaml1="$BATS_TEST_TMPDIR/ignore1.yaml"
|
||||
yaml2="$BATS_TEST_TMPDIR/ignore2.yaml"
|
||||
touch "$yaml1" "$yaml2"
|
||||
|
||||
export INPUT_TRIVYIGNORES="$yaml1,$yaml2" \
|
||||
INPUT_SCAN_TYPE=fs \
|
||||
INPUT_SCAN_REF=./test/data/fs-scan
|
||||
|
||||
run_test_case_fails "Multiple YAML ignore files provided"
|
||||
}
|
||||
|
||||
@test "works with a single YAML file" {
|
||||
yaml="$BATS_TEST_TMPDIR/ignore.yaml"
|
||||
touch "$yaml"
|
||||
|
||||
export INPUT_TRIVYIGNORES="$yaml" \
|
||||
INPUT_SCAN_TYPE=fs \
|
||||
INPUT_SCAN_REF=./test/data/fs-scan
|
||||
|
||||
run ./entrypoint.sh
|
||||
assert_output --partial "Using YAML ignorefile '$yaml'"
|
||||
}
|
||||
|
||||
@test "works with multiple plain ignore files" {
|
||||
plain1="$BATS_TEST_TMPDIR/ignore1"
|
||||
plain2="$BATS_TEST_TMPDIR/ignore2"
|
||||
echo "CVE-1" > "$plain1"
|
||||
echo "CVE-2" > "$plain2"
|
||||
|
||||
trivy_output="$BATS_TEST_TMPDIR/trivy-output.test"
|
||||
|
||||
export INPUT_TRIVYIGNORES="$plain1,$plain2" \
|
||||
INPUT_SCAN_TYPE=fs \
|
||||
INPUT_SCAN_REF=./test/data/fs-scan
|
||||
|
||||
run ./entrypoint.sh
|
||||
assert_output --partial "Found ignorefile '$plain1'"
|
||||
assert_output --partial "Found ignorefile '$plain2'"
|
||||
}
|
||||
Reference in New Issue
Block a user