From f14516dfff50519b0131f71801af51c472984ea6 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 4 May 2026 06:21:23 -0700 Subject: [PATCH 1/4] fix(ci): resolve template injection findings; fix env file for container Move ${{ context }} expressions to env: variables to prevent shell injection at the GitHub Actions template layer. Also filter INPUT_* variables from wolfi-act.github.env before passing it to `docker run --env-file`. INPUT_COMMAND is a multi-line script; Docker's env file parser rejects values containing whitespace, causing exit code 125. The INPUT_* vars are consumed by the action script before the container runs and do not need to be forwarded into the container. Refs: PSEC-923 Co-Authored-By: Claude Sonnet 4.6 --- action.yml | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index f2db9ca..673c083 100644 --- a/action.yml +++ b/action.yml @@ -20,12 +20,17 @@ runs: using: "composite" steps: - shell: bash + env: + INPUT_DEBUG: ${{ inputs.debug }} + INPUT_COMMAND: ${{ inputs.command }} + INPUT_PACKAGES: ${{ inputs.packages }} + INPUT_APKO_IMAGE: ${{ inputs.apko-image }} run: | set -e debug_args= debug_args_image="-exc" - debug='${{inputs.debug}}' + debug="${INPUT_DEBUG}" if [[ "${debug}" == "true" ]]; then echo "[🐙] Enabling debug logging." set -x @@ -33,7 +38,7 @@ runs: debug_args_image="-ec" fi - if [[ '${{inputs.command}}' == '' ]]; then + if [[ "${INPUT_COMMAND}" == '' ]]; then echo "[🐙] Missing input: command" exit 1 fi @@ -51,7 +56,7 @@ runs: - bash EOL - packages='${{inputs.packages}}' + packages="${INPUT_PACKAGES}" if [[ "${packages}" != "" ]]; then for package in $(echo "${packages}" | sed 's/,/\n/g'); do echo " - ${package}" >> ./wolfi-act.apko.config.yaml @@ -62,7 +67,7 @@ runs: eval docker run --rm \ -v ${PWD}:/work \ -w /work \ - '${{ inputs.apko-image }}' \ + "${INPUT_APKO_IMAGE}" \ build \ --arch=x86_64 \ --sbom=false \ @@ -76,14 +81,26 @@ runs: eval docker load < wolfi-act.tar "${debug_args}" echo "done." - env > wolfi-act.github.env + # Capture runner env for the container, excluding INPUT_* vars and + # any var whose value contains embedded newlines (which no + # line-oriented env file format can represent). env -0 gives + # null-terminated records so multi-line values stay in one record; + # we read them in a while loop to avoid grep -v exit-code-1 when + # no records are filtered, which kills the pipeline under pipefail. + while IFS= read -r -d '' record; do + name="${record%%=*}" + value="${record#*=}" + [[ "$name" == INPUT_* ]] && continue + [[ "$value" == *$'\n'* ]] && continue + printf '%s\n' "$record" + done < <(env -0) > wolfi-act.github.env echo "[🐙] Running the following command in ephemeral container image:" - echo '${{ inputs.command }}' + echo "${INPUT_COMMAND}" echo "[🐙] Output:" docker run -i --rm --platform linux/amd64 \ -v ${PWD}:/work \ -w /work \ --env-file wolfi-act.github.env \ wolfi-act:latest-amd64 \ - bash "${debug_args_image}" '${{ inputs.command }}' + bash "${debug_args_image}" "${INPUT_COMMAND}" From 1d493919bab1ed238dcb51aef111f69b16ede83e Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 4 May 2026 06:21:53 -0700 Subject: [PATCH 2/4] fix(ci): add persist-credentials: false and scope workflow permissions Add persist-credentials: false to both checkout steps in ci.yml, since no downstream git operations rely on the credential store. Add permissions: {} at workflow level and explicit contents: read per-job blocks for ci and ci-debug jobs. Refs: PSEC-923 --- .github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cc8f59..2c158d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,9 +7,13 @@ env: IMAGE_REPO: ttl.sh/test-${{ github.job }}-${{ github.run_id }} APKO_CONFIG: https://raw.githubusercontent.com/chainguard-images/images/main/images/maven/config/template.apko.yaml +permissions: {} + jobs: ci: runs-on: ubuntu-latest + permissions: + contents: read # Clone the repository steps: - name: Harden Runner @@ -18,6 +22,8 @@ jobs: egress-policy: audit - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + persist-credentials: false - name: Build, sign, inspect an image using wolfi-act uses: ./ @@ -52,6 +58,8 @@ jobs: ci-debug: runs-on: ubuntu-latest + permissions: + contents: read # Clone the repository steps: - name: Harden Runner @@ -60,6 +68,8 @@ jobs: egress-policy: audit - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + persist-credentials: false - name: Build, sign, inspect an image using wolfi-act uses: ./ From 0852f25c180182328ff45b596156e18fd867c2c1 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 4 May 2026 06:22:35 -0700 Subject: [PATCH 3/4] fix(ci): add pedantic persona and suppress noisy zizmor rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch zizmor CI workflow to pedantic persona to catch all template expansions in run: blocks. Add paths: triggers to zizmor.yaml to ensure changes to .github/zizmor.yml and .github/dependabot.yml are checked. Disable anonymous-definition, undocumented-permissions, and concurrency-limits in .github/zizmor.yml — these are pedantic-only rules with no direct security value that would generate CI noise without actionable remediation. Refs: PSEC-923 --- .github/workflows/zizmor.yaml | 14 ++++++++++++++ .github/zizmor.yml | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/.github/workflows/zizmor.yaml b/.github/workflows/zizmor.yaml index 2a8af57..b2c9140 100644 --- a/.github/workflows/zizmor.yaml +++ b/.github/workflows/zizmor.yaml @@ -6,8 +6,20 @@ name: Zizmor on: pull_request: branches: ['main'] + paths: + - '.github/workflows/**' + - '.github/actions/**' + - 'action.yml' + - '.github/dependabot.yml' + - '.github/zizmor.yml' push: branches: ['main'] + paths: + - '.github/workflows/**' + - '.github/actions/**' + - 'action.yml' + - '.github/dependabot.yml' + - '.github/zizmor.yml' permissions: {} @@ -36,3 +48,5 @@ jobs: - name: Run zizmor uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 + with: + persona: pedantic diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 0812a03..ed96238 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -7,3 +7,12 @@ rules: dependabot-cooldown: config: days: 3 + # Pedantic-only; no security impact — cosmetic/style findings + anonymous-definition: + disable: true + undocumented-permissions: + disable: true + # Pedantic-only; low security value but extremely noisy + # Address concurrency limits as a separate, dedicated effort if desired + concurrency-limits: + disable: true From 91a6dc1b8db36f662c4911c83d5af0aa77460264 Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Mon, 4 May 2026 17:42:57 -0700 Subject: [PATCH 4/4] fix(ci): quote \$PWD in docker run arguments (SC2086) Quote ${PWD} in two docker run -v mount arguments to prevent word splitting on paths with spaces. Co-Authored-By: Claude Sonnet 4.6 --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 673c083..f9c8a9d 100644 --- a/action.yml +++ b/action.yml @@ -65,7 +65,7 @@ runs: printf "[🐙] Building ephemeral container image from Wolfi packages... " eval docker run --rm \ - -v ${PWD}:/work \ + -v "${PWD}":/work \ -w /work \ "${INPUT_APKO_IMAGE}" \ build \ @@ -99,7 +99,7 @@ runs: echo "${INPUT_COMMAND}" echo "[🐙] Output:" docker run -i --rm --platform linux/amd64 \ - -v ${PWD}:/work \ + -v "${PWD}":/work \ -w /work \ --env-file wolfi-act.github.env \ wolfi-act:latest-amd64 \