Skip to main content
All research notes

Supply Chain

7 min read

Your build pipeline is the internal network nobody tests

The build pipeline holds cloud credentials, registry push rights and signing material, and it runs code that dozens of people can change. External tests stop at the perimeter and internal tests start on the corporate network, so the pipeline is usually the most privileged environment nobody has assessed.

Written by the Cloud Security Consultant

External tests stop at the perimeter and internal tests start on the corporate network. The build pipeline sits in neither place, which is how it ends up as the most privileged environment in the organisation with the least assurance work behind it.

A runner typically holds cloud credentials, registry push rights, signing material and a full checkout of the source. It executes code from a repository that dozens of people can write to, on a machine that in many estates has outbound access to everywhere and produces telemetry for nobody. If we get command execution there, the engagement is usually over.

The trigger is the front door

The first thing we read is which events cause a workflow to run and what those events carry with them. Triggers that run against a fork's contents while holding the base repository's secrets are the well known case, and the pattern is broader than one trigger name. Any job that builds an untrusted pull request, evaluates a branch name inside a shell command, or interpolates a title or commit message into a script is executing text an outsider controls. Template injection into a build step needs no exploit code at all. It needs a pull request with a carefully chosen title.

Secrets do not stay in the secret store

Secret handling in pipelines fails in ordinary ways rather than exotic ones. These are the conditions we look for first on an engagement.

  • Long lived cloud keys stored as repository or organisation secrets, where a short lived federated token would do the same job.
  • Secrets exported into the environment for every step in a job, so any dependency pulled during the build can read them.
  • Credentials written to disk by a setup step and left in the workspace, then collected by a later cache or artifact upload.
  • Tokens with organisation wide scope used by a pipeline that only ever touches one repository.
  • Debug logging switched on during an incident and never switched off, with masking quietly failing on encoded values.

The OIDC trust policy is the new firewall rule

Federated identity between a pipeline and a cloud account is a real improvement over static keys, and it moves the risk into a policy document that almost nobody reviews. We read the trust policy before anything else. A condition that checks the issuer and the audience but matches the subject claim with a wildcard will accept a token from any repository in the organisation, and occasionally from any repository anywhere. Pin the subject to the repository, the branch and where possible the deployment environment, and require the audience your provider actually issues.

Runners are hosts, and shared runners are shared hosts

Self hosted runners deserve the scrutiny any other server gets and rarely receive it. A runner that is not ephemeral keeps whatever the last job left behind: cached credentials, a container socket mounted for convenience, a stale checkout. On cloud instances the metadata service is one request away, so an SSRF in a build tool or a malicious build step becomes the instance role and everything attached to it. Mount the container socket only where a job genuinely needs it, run one job per runner instance, block metadata access from build containers, and keep the runner role narrower than the widest thing the pipeline has ever done.

A runner that survives between jobs is a shared workstation with production credentials sitting on it.

Everything the build resolves is code

The build resolves dependencies, and every resolved artifact runs with the pipeline's privileges. Third party actions referenced by a mutable tag, internal package names that a public registry will happily serve first, install scripts that execute during resolution, and base images pulled by floating tag all belong to the same family of problems. Pin by digest, make your internal registry authoritative for your own namespace, and generate a bill of materials during the build rather than reconstructing one afterwards. The OWASP Top 10 CI/CD Security Risks and the NIST Secure Software Development Framework are both sensible checklists to test against.

Testing it without stopping the release train

We scope pipeline work as an assumed breach exercise: give us the access a new contractor gets on their first day, a repository they can open a pull request against, and see how far that reaches. It runs against a copy of the pipeline where one exists, with the same triggers, reduced secrets and an agreed stop point before anything is published to a production registry. The findings are usually fewer than an application test produces and considerably more serious, because the pipeline is where a single mistake reaches every environment at once. Our preference is to test the pattern once, then help the platform team turn the result into the template every new repository inherits.

Written by the Cloud Security Consultant at Nullpath Security. Engagement detail in these notes is anonymised and published only where it cannot identify a client.

  • Attack Surface

    Your attack surface drifts faster than your test cycle

    An annual penetration test measures the estate as it stood on one morning in March. Cloud accounts, DNS records and third party integrations change every week, so the gap between that report and reality starts widening the day it is delivered. Continuous discovery is what keeps the gap small.

    Read the note

  • Engagement Design

    Red team or penetration test: choosing the right engagement

    A penetration test asks how much of a system is broken. A red team engagement asks whether anyone would notice a competent operator coming for a specific objective. Choosing the wrong one wastes the budget and produces a report nobody can act on.

    Read the note

Start here

Find out what an attacker would reach first.

Send us the shape of your environment and a rough deadline. A consultant replies within one business day with a scope, a window and a fixed price. No sales sequence, no discovery deck.

Expires in

Limited time offer

We rebuilt your site for you. Claim it and we handle everything transfer, hosting, and your domain. Then update it anytime, just by asking AI.

Host for only$8 per monthBilled yearly
Claim limited offer now