Przeglądaj źródła

Fix shell injection in validate-frontmatter workflow

The 'Validate frontmatter' step interpolated step output directly into a
double-quoted shell string, allowing a fork PR that adds a file named
e.g. agents/$(curl ...).md to execute arbitrary commands on the runner.

- Pass the file list via env: and reference as "$FILES" so the shell
  never re-evaluates the contents
- Pass PR number via env: for consistency (no ${{ }} inside run:)
- Gate the job on same-repo PRs only, since fork PRs are auto-closed by
  close-external-prs.yml anyway

Impact was bounded (fork PRs get a read-only token with no secrets), but
this closes the RCE-on-runner vector entirely.
Dickson Tsai 4 miesięcy temu
rodzic
commit
068a59e000
1 zmienionych plików z 11 dodań i 4 usunięć
  1. 11 4
      .github/workflows/validate-frontmatter.yml

+ 11 - 4
.github/workflows/validate-frontmatter.yml

@@ -9,6 +9,10 @@ on:
 
 jobs:
   validate:
+    # Fork PRs are auto-closed by close-external-prs.yml, so skip validation
+    # for them entirely. This also prevents untrusted filenames from forks
+    # from ever reaching the shell steps below.
+    if: github.event.pull_request.head.repo.full_name == github.repository
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
@@ -20,16 +24,19 @@ jobs:
 
       - name: Get changed frontmatter files
         id: changed
+        env:
+          GH_TOKEN: ${{ github.token }}
+          PR_NUMBER: ${{ github.event.pull_request.number }}
         run: |
           # Use diff-filter=AMRC to exclude deleted files (D) - only Added, Modified, Renamed, Copied
-          FILES=$(gh pr diff ${{ github.event.pull_request.number }} --name-only --diff-filter=AMRC | grep -E '(agents/.*\.md|skills/.*/SKILL\.md|commands/.*\.md)$' || true)
+          FILES=$(gh pr diff "$PR_NUMBER" --name-only --diff-filter=AMRC | grep -E '(agents/.*\.md|skills/.*/SKILL\.md|commands/.*\.md)$' || true)
           echo "files<<EOF" >> "$GITHUB_OUTPUT"
           echo "$FILES" >> "$GITHUB_OUTPUT"
           echo "EOF" >> "$GITHUB_OUTPUT"
-        env:
-          GH_TOKEN: ${{ github.token }}
 
       - name: Validate frontmatter
         if: steps.changed.outputs.files != ''
+        env:
+          FILES: ${{ steps.changed.outputs.files }}
         run: |
-          echo "${{ steps.changed.outputs.files }}" | xargs bun .github/scripts/validate-frontmatter.ts
+          printf '%s\n' "$FILES" | xargs bun .github/scripts/validate-frontmatter.ts