Masked is not secret: GitLab CI variable theft and backdoored builds
GitLab masking hides values in logs, not from the job. A pipeline edit can read masked variables and exfiltrate them, then ship a backdoored artifact downstream.
Masking sounds protective. In GitLab CI it only redacts a value from the log output. The job still receives the real value in its environment and can do anything it likes with it, including send it somewhere.
How the attack works
An attacker with push or merge-request access edits the pipeline to add a job that references the project’s masked CI/CD variables and pipes them to an external endpoint. The runner executes it, and deploy tokens and a cloud access key stored as variables are read into the job environment despite masking and posted out. A later stage then builds and publishes an artifact containing an added backdoor to the package registry that downstream consumers pull. In ATT&CK terms this is T1195, Supply Chain Compromise, with T1552, Unsecured Credentials, and T1648 for the pipeline execution.
Why it works
Masking is a log-redaction feature, not an access control. Combine that with broad pipeline-edit access and long-lived static secrets any job can read, with no protected branches or required review, and one commit turns into a credential dump plus a supply-chain payload.
How to fix it
Once a job read the variables, the secrets are out, so rotate every CI/CD variable and revoke the project’s deploy tokens and cloud keys, then quarantine the published artifact to stop downstream spread. Removing the job, toggling protected, or blocking an IP leaves the stolen credentials valid. Scope forensics in two halves: the job logs show what was read and sent, and the registry download records show who pulled the artifact. For the class, expose secrets only on protected branches and environments, require review of CI config changes, and replace static keys with short-lived OIDC-federated credentials.
Practice it
We built this as a GraphLattice Range scenario so developers can see masking fail, rotate the right secrets, quarantine the artifact, and move to OIDC.