← All field notes
awsci/cd supply chainfor developers

CodeBuild poisoning: a green pipeline that stole its own credentials

A poisoned buildspec runs with the privileged service role, harvests its credentials, and ships a backdoored artifact through the trusted deploy path. A green pipeline proves little.

A CI/CD build runs with a privileged service role and is trusted to deploy, so a poisoned build step inherits that power and ships through the normal path. A green pipeline does not prove the artifact and the build credentials were not just stolen and tampered with.

How the attack works

An attacker who can edit a buildspec or modify a pipeline stage injects a step that reads the CodeBuild container credential endpoint and the build environment secrets, then posts them to an external destination outside the build VPC’s allowed egress. The same run then deploys a backdoored artifact to production through the normal deploy stage, inheriting the trusted path. CodeBuild logs show the injected credential read, VPC flow logs show the egress, and the pipeline execution and artifact hashes show what shipped. In ATT&CK terms this is T1195, Supply Chain Compromise, with T1552, Unsecured Credentials.

Why it works

The build ran with a broad service role, and buildspec and pipeline edits were neither gated by review nor verified. Egress was unrestricted and artifact provenance was never checked before deploy.

How to fix it

A password reset and rerun do nothing here, because the leaked credentials still work and the tampered artifact may redeploy. Assume the service-role credentials and secrets are burned: freeze the pipeline so it cannot deploy, rotate the service-role trust and every exposed secret, deny old sessions by aws:TokenIssueTime, and quarantine the build artifact. Afterward, least-privilege the service role, gate buildspec and pipeline changes with review and protected branches, restrict build egress to an allowlist, and verify artifact provenance and signing before deploy.

Practice it

We built this as a GraphLattice Range scenario so developers learn to freeze, rotate, and quarantine, and to scope the deployed versions and the stolen credentials’ blast radius.