From 0ba61b7b07eb3f9b9295225919f8a73092ecb3a6 Mon Sep 17 00:00:00 2001 From: Matthew Watkins Date: Tue, 28 Jul 2026 15:53:37 +0100 Subject: [PATCH] Fix: Env-mediate expressions in run blocks zizmor's auditor persona reported 10 template-injection findings in testing.yaml: GitHub expressions expanded directly inside 'run:' blocks, where expansion happens before the shell sees the script and a crafted value could inject commands. Two steps were affected, both reading outputs of the generate-sbom step: the debug dump and the validation step. The validation step already declared an 'env:' block for its matrix values, so the SBOM outputs join it there. Names are kept short (SBOM_MANAGER, SBOM_COUNT) because the step id is long enough that the fuller names push the lines past the 80-column limit yamllint enforces here. The org-wide zizmor workflow now fails a run on any finding at any level, so these informational findings block every new pull request in this repository. zizmor offers an auto-fix for this audit, but it is marked unsafe and on inspection it is: it rewrites the expression in place, leaving it inside the original single quotes, where the shell will not expand it. The original was correct because GitHub expanded the template before the shell ever saw it. These edits were therefore written by hand, with double quotes, and follow the env-before-run shape already used elsewhere in this repository. No behavioural change: the same values reach the same commands. Zizmor now reports no findings for the repository. Co-authored-by: Claude Signed-off-by: Matthew Watkins --- .github/workflows/testing.yaml | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 8070196..773e0df 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -113,16 +113,22 @@ jobs: - name: "Debug: Check SBOM generation outputs" shell: bash + env: + SBOM_OUTCOME: ${{ steps.generate-sbom.outcome }} + SBOM_MANAGER: ${{ steps.generate-sbom.outputs.dependency_manager }} + SBOM_COUNT: ${{ steps.generate-sbom.outputs.component_count }} + SBOM_JSON_PATH: ${{ steps.generate-sbom.outputs.sbom_json_path }} + SBOM_XML_PATH: ${{ steps.generate-sbom.outputs.sbom_xml_path }} run: | echo "🔍 Checking SBOM generation results:" - echo "Step outcome: ${{ steps.generate-sbom.outcome }}" - detected_mgr="${{ steps.generate-sbom.outputs.dependency_manager }}" + echo "Step outcome: $SBOM_OUTCOME" + detected_mgr="$SBOM_MANAGER" echo "Dependency manager: '$detected_mgr'" - component_count="${{ steps.generate-sbom.outputs.component_count }}" + component_count="$SBOM_COUNT" echo "Component count: '$component_count'" - json_path="${{ steps.generate-sbom.outputs.sbom_json_path }}" + json_path="$SBOM_JSON_PATH" echo "JSON path: '$json_path'" - xml_path="${{ steps.generate-sbom.outputs.sbom_xml_path }}" + xml_path="$SBOM_XML_PATH" echo "XML path: '$xml_path'" echo "" echo "🔍 Looking for generated files:" @@ -135,11 +141,16 @@ jobs: MATRIX_DESCRIPTION: ${{ matrix.description }} MATRIX_REPOSITORY: ${{ matrix.repository }} EXPECTED_MANAGER: ${{ matrix.expected_manager }} + SBOM_OUTCOME: ${{ steps.generate-sbom.outcome }} + SBOM_MANAGER: ${{ steps.generate-sbom.outputs.dependency_manager }} + SBOM_COUNT: ${{ steps.generate-sbom.outputs.component_count }} + SBOM_JSON_PATH: ${{ steps.generate-sbom.outputs.sbom_json_path }} + SBOM_XML_PATH: ${{ steps.generate-sbom.outputs.sbom_xml_path }} run: | echo "🔍 Validating SBOM generation for $MATRIX_DESCRIPTION" # Check if SBOM generation succeeded - if [[ "${{ steps.generate-sbom.outcome }}" != "success" ]]; then + if [[ "$SBOM_OUTCOME" != "success" ]]; then desc="$MATRIX_DESCRIPTION" echo "❌ SBOM generation failed for $desc" echo "This might be expected for some repos" @@ -151,7 +162,7 @@ jobs: echo "✅ SBOM generation succeeded" # Validate dependency manager detection - detected="${{ steps.generate-sbom.outputs.dependency_manager }}" + detected="$SBOM_MANAGER" expected="$EXPECTED_MANAGER" if [[ -n "$detected" && "$detected" != "$expected" ]]; then @@ -167,8 +178,8 @@ jobs: xml_found=false # Get the actual file paths from action outputs - json_path="${{ steps.generate-sbom.outputs.sbom_json_path }}" - xml_path="${{ steps.generate-sbom.outputs.sbom_xml_path }}" + json_path="$SBOM_JSON_PATH" + xml_path="$SBOM_XML_PATH" if [[ -n "$json_path" && -f "$json_path" ]]; then json_found=true @@ -187,7 +198,7 @@ jobs: fi # Check component count if available - component_count="${{ steps.generate-sbom.outputs.component_count }}" + component_count="$SBOM_COUNT" if [[ -n "$component_count" && "$component_count" != "0" ]]; then echo "✅ Component count: $component_count" elif [[ "$component_count" == "0" ]]; then