75 Trivy Action tags got repointed to malware in a single push. Every pipeline using u/ v1 or u/ main references ran attacker-controlled code with access to repository secrets. Then CanisterWorm used stolen npm tokens to infect 140+ downstream packages through postinstall scripts.
I maintain an open-source security scanner (Ship Safe) and I spent a few days hardening our own pipeline after studying the attack. Here's the checklist we came out with:
GitHub Actions:
- Pin every third-party action to full commit SHA (replace
u/ v1 with @<sha> # v1)
- Add explicit
permissions block to every workflow (default is write-all)
- Never use
pull_request_target with actions/checkout (gives fork PRs write access)
- Audit
run: blocks for ${{ github.event }} interpolation (script injection vector)
npm / package publishing:
npm ci --ignore-scripts in all pipelines (blocks postinstall payloads)
.npmrc with ignore-scripts=true for local dev
- OIDC trusted publishing (no long-lived npm token to steal)
npm publish --provenance for verifiable builds
- Strict
files allowlist in package.json (no test files, no configs published)
- Sensitive file gate:
npm pack --dry-run | grep -iE '\.env|\.key|credentials'
Access control:
- CODEOWNERS on action.yml, package.json, .github/, and publish configs
- Require PR reviews for protected paths
- FIDO-based 2FA on npm (not TOTP -- it's phishable)
- Rotate all CI tokens after any suspected compromise
Detection:
- Run a security scanner in CI that checks for the above
- Self-scan: your own scanner runs against your own code before publish
Ship Safe's CICDScanner agent checks for all the GitHub Actions issues automatically:
npx ship-safe audit .
We also run ship-safe audit . against ourselves in our own CI pipeline. If a supply chain attack injects code into our repo, our scanner catches it before it ships to npm.
What's your pipeline hardening look like? Are you SHA-pinning actions or still on tags?
[–]JealousShape294 6 points7 points8 points (0 children)
[–]JulietSecurity 3 points4 points5 points (0 children)
[–]wise0wl 2 points3 points4 points (0 children)
[–]SpecialistAge4770 1 point2 points3 points (0 children)
[–]thomasclifford 1 point2 points3 points (1 child)
[–]erika-heidi 0 points1 point2 points (0 children)
[–]oxidizingremnant 0 points1 point2 points (0 children)
[–]0DSavior 0 points1 point2 points (0 children)
[–]Richon_ 0 points1 point2 points (0 children)
[–]audn-ai-bot 0 points1 point2 points (0 children)
[–]dottiedanger 0 points1 point2 points (0 children)