Trivy Action has a script injection via sourced env file in composite action
Description
Trivy Action runs Trivy as GitHub action to scan a Docker container image for vulnerabilities. A command injection vulnerability exists in aquasecurity/trivy-action versions 0.31.0 through 0.33.1 due to improper handling of action inputs when exporting environment variables. The action writes export VAR= lines to trivy_envs.txt based on user-supplied inputs and subsequently sources this file in entrypoint.sh. Because input values are written without appropriate shell escaping, attacker-controlled input containing shell metacharacters (e.g., $(...), backticks, or other command substitution syntax) may be evaluated during the sourcing process. This can result in arbitrary command execution within the GitHub Actions runner context. Version 0.34.0 contains a patch for this issue. The vulnerability is exploitable when a consuming workflow passes attacker-controlled data into any action input that is written to trivy_envs.txt. Access to user input is required by the malicious actor. Workflows that do not pass attacker-controlled data into trivy-action inputs, workflows that upgrade to a patched version that properly escapes shell values or eliminates the source ./trivy_envs.txt pattern, and workflows where user input is not accessible are not affected.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Command injection in aquasecurity/trivy-action (0.31.0–0.33.1) allows arbitrary code execution when attacker-controlled input is written to action inputs due to unsanitized environment variable export.
Vulnerability
A command injection vulnerability exists in aquasecurity/trivy-action versions 0.31.0 through 0.33.1 due to improper handling of action inputs when exporting environment variables [2][4]. The action writes export VAR= lines to trivy_envs.txt based on user-supplied inputs and subsequently sources this file in entrypoint.sh. Because input values are written without appropriate shell escaping, attacker-controlled input containing shell metacharacters (e.g., $(...), backticks, or other command substitution syntax) may be evaluated during the sourcing process [2].
Exploitation
The vulnerability is exploitable when a consuming workflow passes attacker-controlled data into any action input that is written to trivy_envs.txt. A representative pattern involves incorporating untrusted pull request metadata into an action parameter, such as output: "trivy-${{ github.event.pull_request.title }}.sarif". If the pull request title contains shell syntax, it is executed when the generated environment file is sourced [4]. Access to user input is required; workflows that do not pass attacker-controlled data or where user input is not accessible are not affected [2].
Impact
Successful exploitation leads to arbitrary command execution within the GitHub Actions runner context. This can allow an attacker to exfiltrate secrets, modify the build output, or perform other malicious actions within the CI/CD pipeline [2][4]. The vulnerability has a CVSS score of 6.9 (moderate) due to high privileges required and user interaction [4].
Mitigation
Version 0.34.0 contains a patch that properly escapes shell values and eliminates the vulnerable source ./trivy_envs.txt pattern [3][4]. Users should upgrade to the latest version. Additionally, workflows should avoid passing untrusted input into action parameters that are exported as environment variables [2].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
aquasecurity/trivy-actionGitHub Actions | >= 0.31.0, < 0.34.0 | 0.34.0 |
Affected products
2- Range: >=0.31.0, <=0.33.1
- aquasecurity/trivy-actionv5Range: >= 0.31.0, < 0.34.0
Patches
2bc61dc55704eMerge commit from fork
1 file changed · +3 −2
action.yaml+3 −2 modified@@ -183,9 +183,10 @@ runs: local input_value="$2" local default_value="$3" - if [ ! -z "$input_value" ] && [ "$input_value" != "$default_value" ]; then + if [ -n "$input_value" ] && [ "$input_value" != "$default_value" ]; then # If action was provided with explicit input by the caller set that - echo "export $var_name=$input_value" >> trivy_envs.txt + # Use printf %q to safely escape special characters and prevent command injection + printf 'export %s=%q\n' "$var_name" "$input_value" >> trivy_envs.txt fi }
7aca5acc9500fix: Trivy action inputs leaking between invocations (#422) (#454)
4 files changed · +74 −3
action.yaml+30 −2 modified@@ -147,21 +147,41 @@ runs: env: GITHUB_ACTION_PATH: ${{ github.action_path }} + # Create and Clear Trivy Envs file + # See #422 for context + - name: Clear Trivy Envs file + shell: bash + run: | + rm -f trivy_envs.txt + touch trivy_envs.txt + - name: Set Trivy environment variables shell: bash run: | # Note: There is currently no way to distinguish between undefined variables and empty strings in GitHub Actions. # This limitation affects how we handle default values and empty inputs. # For more information, see: https://github.com/actions/runner/issues/924 - # Function to set environment variable only if the input is provided and different from default + # The following logic implements the configuration priority described in the README: + # + # Inputs + # Environment Variables + # Config File + # Defaults + # + # As noted above defaults are awkward to handle as GitHub Actions will inject those values as the input + # if the caller doesn't provide them, thus if the input matches the default we don't set it as we + # can't tell the difference. Plus if we did set it when it was the default value then it could potentially + # override an external environment variable, or something in the callers configuration file, which then wouldn't + # match the configuration priority that is documented. set_env_var_if_provided() { local var_name="$1" local input_value="$2" local default_value="$3" if [ ! -z "$input_value" ] && [ "$input_value" != "$default_value" ]; then - echo "$var_name=$input_value" >> $GITHUB_ENV + # If action was provided with explicit input by the caller set that + echo "export $var_name=$input_value" >> trivy_envs.txt fi } @@ -202,3 +222,11 @@ runs: # For Trivy TRIVY_CACHE_DIR: ${{ inputs.cache-dir }} # Always set + + # Remove Trivy envs to keep envs within this action and avoid env leaks + # See #422 for context + - name: Remove Trivy Envs file + if: ${{ always() }} + shell: bash + run: | + rm -f trivy_envs.txt
entrypoint.sh+9 −1 modified@@ -1,6 +1,14 @@ #!/bin/bash set -euo pipefail +# 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 +# See #422 for more context around this +if [ -f ./trivy_envs.txt ]; then + source ./trivy_envs.txt +fi + # Set artifact reference scanType="${INPUT_SCAN_TYPE:-image}" scanRef="${INPUT_SCAN_REF:-.}" @@ -54,4 +62,4 @@ if [ "${TRIVY_FORMAT:-}" = "github" ]; then fi fi -exit $returnCode \ No newline at end of file +exit $returnCode
README.md+7 −0 modified@@ -854,6 +854,13 @@ Following inputs can be used as `step.with` keys: ### Environment variables You can use [Trivy environment variables][trivy-env] to set the necessary options (including flags that are not supported by [Inputs](#inputs), such as `--secret-config`). +**NB** In some older versions of the Action there was a bug that caused inputs from one call to the Action to leak +over to subsequent calls to the Action. This could cause workflows that call the Action multiple times e.g. to run +multiple scans, or the same scans with different output formats, to not produce the desired output. You can see if this +is the case by looking at the GitHub Actions step information, if the `env` section shown in your Actions output +contains `TRIVY_*` environment variables you did not explicitly set then you may be affected by this bug and should +upgrade to the latest Action version. + ### Trivy config file When using the `trivy-config` [Input](#inputs), you can set options using the [Trivy config file][trivy-config] (including flags that are not supported by [Inputs](#inputs), such as `--secret-config`).
test/test.bats+28 −0 modified@@ -39,6 +39,7 @@ function reset_envs() { for var in $(env | grep '^TRIVY_\|^INPUT_' | cut -d= -f1); do unset "$var" done + rm -f trivy_envs.txt } function compare_files() { @@ -149,4 +150,31 @@ function compare_files() { ./entrypoint.sh compare_files tfvars.json ./test/data/with-tf-vars/report.json reset_envs +} + +@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 +} + +@test "trivy image via environment file overrides env leakages" { + # trivy image --severity CRITICAL --output image.test knqyf263/vuln-image:1.2.3 + # Action injects inputs into the script via environment variables + # 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 } \ No newline at end of file
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-9p44-j4g5-cfx5ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-26189ghsaADVISORY
- github.com/aquasecurity/trivy-action/commit/7aca5acc9500b463826cc47a47a65ad7d404b045ghsax_refsource_MISCWEB
- github.com/aquasecurity/trivy-action/commit/bc61dc55704e2d5704760f3cdab0d09acf16e4caghsax_refsource_MISCWEB
- github.com/aquasecurity/trivy-action/security/advisories/GHSA-9p44-j4g5-cfx5ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.