GitHub Actions is the weakest link

TLDR

  • Every major open source supply chain incident in the past 18 months traces back to a .github/workflows YAML file exploiting documented GitHub Actions features.

Key Takeaways

  • Five recurring primitives drive every incident: pull_request_target and issue_comment triggers handing write tokens to untrusted workflows, ${{ }} template injection into shell, mutable action tags resolvable across the shared fork object pool, and a cache that silently crosses trust boundaries.
  • The tj-actions compromise exposed 23,000 repos because action versions are mutable git refs – a force-pushed tag pointing at a dangling object in the fork network is executable without any upstream branch ever holding it.
  • OIDC trusted publishing (PyPI, npm, RubyGems, crates.io) concentrated credential trust onto GitHub Actions workflows; an attacker targeting PyPI today reads workflow files, not phishing maintainers.
  • GitHub’s published security roadmap includes a workflow lockfile, scoped secrets, and an egress firewall – all opt-in, all 3-6 months out, arriving three years after the lockfile issue was closed as “not planned.”
  • zizmor catches dangerous-triggers, cache-poisoning, unpinned-uses, template-injection, and excessive-permissions; the elementary-data incident was flagged High/High three weeks before it fired.

Hacker News Comment Review

  • Consensus is that pinning actions to full commit SHAs rather than tags is the correct baseline, but even SHA pins are insufficient without verifying the SHA is reachable from a canonical branch – the fork object pool loophole means a “pinned” SHA can still resolve to unreviewed attacker code.
  • Several commenters pointed to zizmor, ratchet, and runtime sandboxes like hasp as practical mitigations today, while others argued the root cause is YAML-as-programming-language and pushed for first-class scripting runtimes or Dagger-style portable CI.
  • There is frustration that GitHub/Microsoft appear slow relative to the severity: one commenter called the product “asleep at the wheel” given the number of mature alternatives and acquisition targets already available.

Notable Comments

  • @electricapps: Built hasp, an open-source GHA runtime sandbox; first check enforces SHA pinning and verifies the SHA is reachable from a real upstream branch, directly closing the fork-pool loophole.
  • @pimeys: Sidesteps the problem by using GHA only as a thin caller with all logic in Nix scripts, making CI runs reproducible locally.

Original | Discuss on HN