CI/CD Secret Exposure
A public CI workflow echoes a secret into a world-readable build log, so an attacker lifts the deploy key. Remove the echo, pass secrets via quoted env vars, avoid interpolating untrusted input into run steps, pin actions by SHA, and rotate the key.
What Is CI/CD Secret Exposure?
CI/CD secret exposure is the failure that occurs when a build pipeline reveals a secret or runs attacker-controlled input, and it lives in the pipeline configuration itself rather than in application code. The classic shape is a workflow step that echoes an environment secret for debugging, so the value prints into a build log, and on a public repository that log is world-readable. A related flaw in the same file is workflow script injection: untrusted input, such as a pull-request title or a branch name, is interpolated straight into a run step, so the input can execute as shell commands in the pipeline. This exercise puts you on both sides. As Bob, an attacker who reads public CI build logs and inspects workflow files, you browse Vellmoor's public build runs, find the step that echoes a deploy key, copy the key straight from the log, and use it to push an artifact and reach the infrastructure behind the pipeline. As Alice, a build engineer at Vellmoor who owns the CI workflows, you receive a Security Operations alert that a secret was found in a public Actions log, open the workflow file, and find both the echo of the secret and an unquoted interpolation of untrusted input into a run step. You ship the fix: remove the echo, pass the secret through an env variable with quoting so it is used and not printed, stop interpolating untrusted input into shell steps, pin third-party actions by commit SHA so a moved tag cannot swap in malicious code, restrict what pull-request-triggered runs can access, and rotate the leaked deploy key because masking alone does not undo an exposure that already happened. The exercise closes with quiz questions on how a secret reaches a log, why rotation is required and masking is not enough, what workflow script injection is, and why pinning actions by commit SHA matters.
What You'll Learn in CI/CD Secret Exposure
- Recognize CI/CD secret exposure: a workflow step that echoes or prints a secret writes it into a build log, and on a public run that log is world-readable to anyone
- Understand workflow script injection: untrusted input such as a pull-request title or branch name interpolated into a run step can execute as shell commands in the pipeline
- Apply the fix for a leaked secret: remove the echo, pass the secret through an env variable with quoting so it is used rather than printed, and rotate the key because it already appeared in a readable log
- Harden the pipeline: bind untrusted input through quoted env variables instead of interpolating it into run steps, and restrict what pull-request-triggered runs can access
- Pin third-party actions by commit SHA so a moved tag cannot silently swap in malicious code, and audit workflow files for the same echo and interpolation patterns
CI/CD Secret Exposure — Training Steps
-
Public build logs
Vellmoor builds its edge transcoder in the open, so the repository's pipeline is public and so is everything it prints. Bob does not need an account, an invite, or a single exploit to start. He opens the run history and reads.
-
Open a release run
Integration runs only build and test. The Release workflow is the interesting one, because a release has to reach production, and reaching production takes a credential. Bob opens the most recent release run.
-
Expand the deploy step
The run is a list of steps, each one collapsed. Checkout and build are routine. The step Bob wants is the one that talks to production, because that is where a credential has to be used.
-
The token, in plain text
The step opens and the credential is simply there. Someone added a line to print the token while chasing a broken deploy, the deploy got fixed, and the line stayed. Bob does not have to crack anything. He selects the value and copies it.
-
How long has it been printing
One log line is one copy. Bob goes back to the run history and searches every run's output for the token's prefix, to find out how long this has been happening. The answer decides how many people could already be holding it.
-
What the token can reach
Before using it, Bob asks Vellmoor's deploy service what this credential is allowed to do. He calls the environments endpoint with the token in an Authorization header. The answer comes back without a challenge, and it is not limited to a test environment.
-
Ship his own build
Bob does not need to touch the repository, open a pull request, or wait for a review. The deploy service does not care where an image comes from, only that the caller holds a valid token. He points production at an image on his own registry.
-
Knowledge check
You just watched a production credential picked up out of a build log with no exploit involved. Lock in how it got there.
-
The alert lands
You own Vellmoor's CI workflows. This morning platform security has both halves of a bad night: a credential found in public output, and a production deployment nobody scheduled.
-
See it on your own pipeline
Reports of a leak are one thing. You open the run the alert points at, to see what your pipeline actually published.