Skip to content

security: harden CI workflows — pin actions, scope tokens, fix dispatch branch injection (PER-8691/8692/8693)#1164

Open
Shivanshu-07 wants to merge 1 commit into
masterfrom
security/PER-8691-92-93-ci-hardening
Open

security: harden CI workflows — pin actions, scope tokens, fix dispatch branch injection (PER-8691/8692/8693)#1164
Shivanshu-07 wants to merge 1 commit into
masterfrom
security/PER-8691-92-93-ci-hardening

Conversation

@Shivanshu-07

@Shivanshu-07 Shivanshu-07 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Breaks the percy-ember supply-chain attack chains (deadline 2026-06-21), whose entry points are all CI weaknesses:

Chain Entry point
PER-8691 (C-001) Build-time redirect → eval'd RCE in CI test browser
PER-8692 (C-002) Hijacked mutable Action tag + broad GITHUB_TOKEN → backdoored npm release
PER-8693 (C-003) Compromised CI action injects PERCY_SERVER_ADDRESS → test-runtime RCE

Changes

  • SHA-pin every third-party action across all workflows (checkout, setup-node, cache, release-drafter, action-regex-match, stale) — a hijacked mutable tag can no longer inject code or exfiltrate NPM_TOKEN.
  • Least-privilege permissions on every workflow (top-level contents: read; changelog → contents/PR write; stale → issues/PR write), removing the write-all GITHUB_TOKEN that amplified the chains.
  • Fix the workflow_dispatch branch-injection in test.yml: the user-supplied branch is bound to an env var (CLI_BRANCH) and quoted in git clone, instead of interpolating ${{ github.event.inputs.branch }} into the shell.

Verification

All 7 workflow YAMLs parse; every workflow declares permissions:; zero unpinned uses:; the dispatch branch is no longer interpolated inline.

Closes the CI-supply-chain entry of PER-8691/8692/8693. The runtime component findings (PER-8681 PERCY_SERVER_ADDRESS SSRF, PER-8682 eval of network JS) are separate code fixes tracked on those tickets.

🤖 Generated with Claude Code

…ch branch injection (PER-8691/8692/8693)

Breaks the percy-ember supply-chain attack chains (C-001/C-002/C-003), whose
entry points are CI weaknesses:

- SHA-pin every third-party action across all workflows (checkout, setup-node,
  cache, release-drafter, action-regex-match, stale) so a hijacked mutable tag
  can't inject code into the release/test pipeline or exfiltrate NPM_TOKEN.
- Add least-privilege `permissions` to every workflow (top-level
  `contents: read`; changelog → contents/PR write; stale → issues/PR write),
  removing the implicit write-all GITHUB_TOKEN that amplified the chains.
- Fix the workflow_dispatch branch-injection in test.yml: bind the
  user-supplied branch to an env var (`CLI_BRANCH`) and quote it in the
  `git clone` instead of interpolating `${{ github.event.inputs.branch }}`
  into the shell.

The runtime component findings for this repo (F-004 PERCY_SERVER_ADDRESS SSRF,
F-005 eval of network-fetched JS) are separate code fixes tracked on
PER-8681 / PER-8682.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Shivanshu-07

Copy link
Copy Markdown
Contributor Author

Impact analysis + automated review

Impact — no existing functionality breaks. CI-config only (.github/workflows/*): SHA-pins actions, adds least-privilege permissions:, and moves the workflow_dispatch branch input into a quoted env var. The dispatch fix passes the same branch value — only the shell-injection vector is removed; legitimate dispatch still works. npm publish/changelog/stale token scopes are all correct.

/stack:pr-review: PASS — no Critical/High findings; all pinned SHAs verified. Minor follow-ups (non-blocking, pre-existing): regex guard rejects dotted branch names; deprecated ::set-output.

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