From e867ee02cef36f93264e4c89b16f551e4221b8ca Mon Sep 17 00:00:00 2001 From: pdewilde Date: Mon, 17 Nov 2025 13:42:34 -0800 Subject: [PATCH 1/5] Add action scaning workflow --- .github/workflows/action_scanning.yml | 100 ++++++++++++++-------- .github/workflows/action_scanning_old.yml | 39 +++++++++ 2 files changed, 104 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/action_scanning_old.yml diff --git a/.github/workflows/action_scanning.yml b/.github/workflows/action_scanning.yml index 6bca219..20ec772 100644 --- a/.github/workflows/action_scanning.yml +++ b/.github/workflows/action_scanning.yml @@ -1,39 +1,69 @@ -### Required actions to scan GitHub action workflows for security issues. -name: 'Scan GitHub Action workflows files for security issues' +name: 'GitHub Admin: Actions Workflow Security Scan' + on: - pull_request: {} -permissions: - contents: 'read' - security-events: 'write' - actions: 'read' + pull_request: + paths: + - '.github/workflows/**/*.yml' + - '.github/workflows/**/*.yaml' + - '.github/actions/**/*.yml' + - '.github/actions/**/*.yaml' + jobs: - semgrep: - name: 'semgrep-oss/scan' + scan-pr: + permissions: + contents: 'read' + if: "github.event_name == 'pull_request'" runs-on: 'ubuntu-latest' - container: - image: 'index.docker.io/semgrep/semgrep@sha256:85782eaf09692e6dfb684cd3bad87ef315775814b01f76b4d15582e4ca7c1c89' # ratchet:semgrep/semgrep - # Skip any PR created by dependabot to avoid permission issues: - if: (github.actor != 'dependabot[bot]') steps: - - name: 'Checkout Code' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4 - - name: 'Checkout Workflow Config' - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4 - env: - GH_REPO_OWNER: ${{ github.repository_owner }} - with: - repository: 'google/github-team' - path: action_scanning - - name: 'Run Actions semgrep scan' - run: 'semgrep scan --sarif --config action_scanning/semgrep-rules --config "p/github-actions" - --sarif-output semgrep-results-actions.sarif || true' - - name: 'Save Actions SARIF results as artifact' - uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4 - with: - name: 'semgrep-scan-results-actions' - path: 'semgrep-results-actions.sarif' - - name: 'Upload Actions SARIF result to the GitHub Security Dashboard' - uses: 'github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841' # ratchet:github/codeql-action/upload-sarif@v3 - with: - sarif_file: 'semgrep-results-actions.sarif' - if: always() + - name: 'Checkout PR Code' + uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5 + + - name: 'Check for Workflow Files' + id: 'check_files' + run: | + FOUND_FILES=$(find . -type f -regextype posix-extended -regex '\./\.github/(workflows|actions)/.*\.ya?ml' | head -n 1) + if [ -n "$FOUND_FILES" ]; then + echo "workflow_files_found=true" >> "$GITHUB_OUTPUT" + else + echo "workflow_files_found=false" >> "$GITHUB_OUTPUT" + fi + - name: 'Initialize CodeQL' + if: "steps.check_files.outputs.workflow_files_found == 'true'" + uses: 'google/codeql-action/init@014f16e7ab1402f30e7c3329d33797e7948572db' # ratchet:google/codeql-action/init@v4 + with: + languages: 'actions' + queries: 'security-extended' + - name: 'Perform CodeQL Analysis' + if: "steps.check_files.outputs.workflow_files_found == 'true'" + id: 'codeql_analysis' + uses: 'google/codeql-action/analyze@014f16e7ab1402f30e7c3329d33797e7948572db' # ratchet:google/codeql-action/analyze@v4 + with: + upload: 'never' + + - name: 'Check for Vulnerabilities and Set Status' + id: 'vuln_check' + if: "steps.check_files.outputs.workflow_files_found == 'true'" + run: | + SARIF_FILE="${{ steps.codeql_analysis.outputs.sarif-output }}/actions.sarif" + if [ ! -f "$SARIF_FILE" ]; then + echo "SARIF file not found at $SARIF_FILE" + exit 1 + fi + RESULT_COUNT=$(jq '.runs[0].results | length' "$SARIF_FILE") + if [ "$RESULT_COUNT" -gt 0 ]; then + echo "::error::CodeQL found $RESULT_COUNT potential vulnerabilities." + echo "---" + jq -r '.runs[0].results[] | ("Rule ID: " + .ruleId + "\nMessage: " + .message.text + "\nFile: " + .locations[0].physicalLocation.artifactLocation.uri + "\nLine: " + (.locations[0].physicalLocation.region.startLine | tostring) + "\n---")' "$SARIF_FILE" + exit 1 + else + echo "No vulnerabilities found. Check passed." + fi + + - name: 'Upload SARIF file on failure' + if: "failure() && steps.vuln_check.conclusion == 'failure'" + uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4 + with: + name: 'sarif-report' + path: '${{ steps.codeql_analysis.outputs.sarif-output }}/actions.sarif' + retention-days: 1 + overwrite: 'true' diff --git a/.github/workflows/action_scanning_old.yml b/.github/workflows/action_scanning_old.yml new file mode 100644 index 0000000..6bca219 --- /dev/null +++ b/.github/workflows/action_scanning_old.yml @@ -0,0 +1,39 @@ +### Required actions to scan GitHub action workflows for security issues. +name: 'Scan GitHub Action workflows files for security issues' +on: + pull_request: {} +permissions: + contents: 'read' + security-events: 'write' + actions: 'read' +jobs: + semgrep: + name: 'semgrep-oss/scan' + runs-on: 'ubuntu-latest' + container: + image: 'index.docker.io/semgrep/semgrep@sha256:85782eaf09692e6dfb684cd3bad87ef315775814b01f76b4d15582e4ca7c1c89' # ratchet:semgrep/semgrep + # Skip any PR created by dependabot to avoid permission issues: + if: (github.actor != 'dependabot[bot]') + steps: + - name: 'Checkout Code' + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4 + - name: 'Checkout Workflow Config' + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4 + env: + GH_REPO_OWNER: ${{ github.repository_owner }} + with: + repository: 'google/github-team' + path: action_scanning + - name: 'Run Actions semgrep scan' + run: 'semgrep scan --sarif --config action_scanning/semgrep-rules --config "p/github-actions" + --sarif-output semgrep-results-actions.sarif || true' + - name: 'Save Actions SARIF results as artifact' + uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4 + with: + name: 'semgrep-scan-results-actions' + path: 'semgrep-results-actions.sarif' + - name: 'Upload Actions SARIF result to the GitHub Security Dashboard' + uses: 'github/codeql-action/upload-sarif@1b549b9259bda1cb5ddde3b41741a82a2d15a841' # ratchet:github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'semgrep-results-actions.sarif' + if: always() From e19811db4ce6ec98cdc7947775ce43a965bb75f2 Mon Sep 17 00:00:00 2001 From: pdewilde Date: Mon, 17 Nov 2025 13:46:10 -0800 Subject: [PATCH 2/5] comment google --- .github/workflows/action_scanning.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/action_scanning.yml b/.github/workflows/action_scanning.yml index 20ec772..5cbc365 100644 --- a/.github/workflows/action_scanning.yml +++ b/.github/workflows/action_scanning.yml @@ -1,4 +1,4 @@ -name: 'GitHub Admin: Actions Workflow Security Scan' +name: 'Google GitHub Admin: Actions Workflow Security Scan' on: pull_request: From b8dcaeb09087ddd9087af1c28c88e7267c45d09b Mon Sep 17 00:00:00 2001 From: pdewilde Date: Mon, 17 Nov 2025 13:48:56 -0800 Subject: [PATCH 3/5] better follow my own rules --- .github/workflows/action_scanning.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/action_scanning.yml b/.github/workflows/action_scanning.yml index 5cbc365..5664319 100644 --- a/.github/workflows/action_scanning.yml +++ b/.github/workflows/action_scanning.yml @@ -8,6 +8,10 @@ on: - '.github/actions/**/*.yml' - '.github/actions/**/*.yaml' +permissions: + contents: 'read' + actions: 'write' # Upload artifact + jobs: scan-pr: permissions: From 4e236ee29aa767693251745559668f989a2835f0 Mon Sep 17 00:00:00 2001 From: pdewilde Date: Mon, 17 Nov 2025 13:55:41 -0800 Subject: [PATCH 4/5] Add custom scan list --- .github/workflows/action_scanning.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/action_scanning.yml b/.github/workflows/action_scanning.yml index 5664319..1ae6082 100644 --- a/.github/workflows/action_scanning.yml +++ b/.github/workflows/action_scanning.yml @@ -7,6 +7,21 @@ on: - '.github/workflows/**/*.yaml' - '.github/actions/**/*.yml' - '.github/actions/**/*.yaml' +env: + ACTIONS_SUITE_CONTENT: | + - qlpack: codeql/actions-queries + - include: + id: actions/envvar-injection/critical + - include: + id: actions/envpath-injection/critical + - include: + id: actions/cache-poisoning/poisonable-step + - include: + id: actions/artifact-poisoning/critical + - include: + id: actions/untrusted-checkout/critical + - include: + id: actions/untrusted-checkout/high permissions: contents: 'read' @@ -31,12 +46,22 @@ jobs: else echo "workflow_files_found=false" >> "$GITHUB_OUTPUT" fi + + - name: 'Create CodeQL Query Suite' + if: "steps.check_files.outputs.workflow_files_found == 'true'" + run: 'echo "${{ env.ACTIONS_SUITE_CONTENT }}" > actions-suite.qls' + - name: 'Initialize CodeQL' if: "steps.check_files.outputs.workflow_files_found == 'true'" uses: 'google/codeql-action/init@014f16e7ab1402f30e7c3329d33797e7948572db' # ratchet:google/codeql-action/init@v4 with: languages: 'actions' - queries: 'security-extended' + config: | + name: 'Custom Action Scan' + disable-default-queries: true + queries: + - uses: ./actions-suite.qls + - name: 'Perform CodeQL Analysis' if: "steps.check_files.outputs.workflow_files_found == 'true'" id: 'codeql_analysis' From 7178e18488bfb0346851112cf969778d30ff4cfc Mon Sep 17 00:00:00 2001 From: pdewilde Date: Mon, 17 Nov 2025 13:58:45 -0800 Subject: [PATCH 5/5] Exclude file from linting due to conflicting lint rules --- .yamlfmt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.yamlfmt b/.yamlfmt index 0a3382f..4e063f0 100644 --- a/.yamlfmt +++ b/.yamlfmt @@ -1,3 +1,5 @@ formatter: max_line_length: 100 trim_trailing_whitespace: true +exclude: + - .github/workflows/action_scanning.yml