← NIST SP 800-204D
5.1.4
Secure code commits
Commits should be attributable and should not carry secrets, which includes scanning and blocking secrets before they are pushed. Signed commits and push protection sit here.
Summary in ghtier's words. Read NIST 800-204D's own text
Incidents (6)
Last 12 months (3): ChainDrop: a hijacked maintainer account publishes through trusted publishing, Megalodon: mass backdooring of CI workflows, GlassWorm: editor extensions that steal GitHub tokens and force-push
2026
- ChainDrop: a hijacked maintainer account publishes through trusted publishingOrganization August 2026
- Megalodon: mass backdooring of CI workflowsOrganization May 2026
2025
- GlassWorm: editor extensions that steal GitHub tokens and force-pushUser October 2025
- GhostActionOrganization September 2025
2024
- Mercedes-Benz source code exposureUser January 2024
2023
- Dependabot impersonationUser July 2023
Attack path techniques used
- Push directly, without review (Submit malicious code)
- Force push or delete a protected branch (Delete code or cover tracks)
- Delete branches and workflow runs (Delete code or cover tracks)
- Push a release tag to an unreviewed commit (Point a release tag at a bad commit)
- Add a workflow that dumps secrets (Steal CI secrets and tokens)
- Publish a malicious version with a stolen token (Poison the build or published package)
- Clone private repos with a stolen token (Read or expose private code)
- Leave a dormant workflow behind (Keep access)
Checklist items
The fixes for those techniques.
- Branch protection on default/release branches: required reviews + required status checks
- Rulesets applied: push restriction, tag protection, sensitive file-path protection
- Deletion and force-pushes prevented on critical branches
- Require signed commits on the default branch of sensitive repos
- Enable audit logging and export it to a SIEM for retention and detection
- CODEOWNERS in place, required on sensitive paths
- Inventory every Actions secret and its visibility/scope; the results are usually surprising
- Cloud credentials migrated from static keys to OIDC federation, scoped to repo + branch
- Adopt artifact attestations for build provenance on published binaries/images
- Publish packages with trusted publishing (OIDC) instead of long-lived registry tokens
- Put production secrets in environments with required reviewers
- Write and rehearse a credential-rotation runbook before you need it
- Set an organization-wide maximum PAT lifetime (90 days is a reasonable default)
- Disable classic PATs organization-wide, forcing migration to fine-grained PATs
- Audit and revoke stale PATs, unused SSH keys, and inactive accounts
- Enforce an IP allow list for Git and web UI access from trusted ranges
Permissions involved
The GitHub permissions those incidents abused.