Filters
How to search
  • Plain words find names, texts and examples.
  • "two words" finds the exact phrase.
  • --name or -x finds an option.
  • #word looks only inside commands.
  • @grep finds lessons and labs that use grep.
  • Filters: cat:network · in:labs · in:notes · level:rhcsa · ch:8 · root:yes. Put ! before a word to leave it out. OR between words means one of them.
  • ↑ ↓ to move · Enter to open · Esc to close · / to search

Git & CI/CDDevSecOps series

A pipeline attack, minute by minute

The alert did not fire when the pull request opened. It fired nineteen days later, when someone read a bill.

Quick reference

TimeStepWhat happens
0mPush to a forkThe attacker forks the repo and opens a pull request.
1mToken issuedpull_request_target hands the job a write token and secrets.
2mCache poisonedA package cache the release build trusts now holds bad bytes.
4mSecrets readThe job prints its environment; the log is readable.
6mArtifact publishedThe write token pushes a new image tag to the registry.
19dDetectionA bill, an audit log or a scanner finally connects the dots.

Explained

The first minutes

0m. Push to a fork. The attacker forks the repository and opens a pull request from a branch. Nothing looks unusual: a fork, a commit and a green check requested.

1m. Token issued. The workflow uses pull_request_target. It runs from the default branch, so the job receives the base repository's token and its secrets, and the token can write.

2m. Cache poisoned. The job writes an entry into a package cache the release workflow trusts. A later restore unpacks it and treats the contents as its own build output.

The next minutes

4m. Secrets read. A step prints its environment, or reads a file the token can reach. The run log is readable to anyone with repository access.

6m. Artifact published. The write token pushes a new tag to the registry, or edits a release. The image carries the project's name and a plausible version.

The detection

19d. Detection. A cloud bill, an audit log or a scanner finally connects the fork to the image. The mean time to detect is measured in weeks because nothing watches the pipeline itself.

The honest caveat: this is a composite of documented cases, and the timings are illustrative. GitHub's 2026 cache and checkout changes close the easiest version, but the chain still runs wherever secrets are reachable.

The lesson: the pipeline is a production system, so alert on it like one.

In one line

Detection is the last step. The first five happen before anyone looks.

Read the log

gh run view --log

More notes: Git & CI/CD

Open in the notes app: search, filters, copy This note on GitHub