- The Rust team reported that Miri saved all environment variables to target/, which GitHub Actions caches could then expose to pull requests.
- Its scan found one affected repository and seven that should be cautious. The team's scan was probably imperfect.
- Teams running Miri should clear caches and consider rotating secrets. All teams should keep secrets away from jobs that write to caches pull requests can read.
Many teams put real effort into guarding secrets at the front door. They store tokens in a vault and pass them to build jobs with care. The harder question is what those jobs leave behind. A recent report from the Rust project shows how a tool can copy a secret to disk, and how a speed-up feature can then hand that copy to the wrong people.
What the Rust team reported
Someone alerted the Rust Security Response Team to a habit in Miri, a tool run through the cargo miri command. Miri writes a copy of every environment variable into the target/ directory. Environment variables are the settings a build job reads, and teams often use them to pass secrets such as access tokens.
On its own, the team said, this is not necessarily a vulnerability. The problem appears when it meets GitHub Actions caching. Teams cache directories between runs to make builds faster. Rust projects often speed up CI by caching built binaries, and sometimes the target/ directory.
How a cached file becomes an exposure
A typical setup lets runs on the main branch write to the cache. Pull requests can only read from it. That rule is meant to prevent cache poisoning, where an outsider plants bad files.
Here, the read access is the problem. If a main-branch job had secrets in its environment and ran Miri, those secrets were saved into target/. The cache then held them. A pull request could read the cache and extract them.
The team lists the conditions that must all hold. The step running cargo miri has secrets in its environment. The workflow caches the target directory, usually through actions/cache or swatinem/rust-cache. And pull requests can access that cache, which the team calls common and often intended.
Why the attacker's bar is low
The people who can start a pull request build are, in effect, anyone able to open a pull request on your repository. GitHub asks a maintainer to approve the first one. After that, CI reruns on every push. So anyone who has landed one change before can trigger a run that reads the cache.
Covering tracks is easy too. The person can push a second commit to overwrite the first. The Rust team notes that GitHub sometimes hides overwritten commits in its interface. Run logs and replaced commits also disappear after a few months. A leak could be hard to see, and hard to investigate later.
What was fixed, and what was found
The short-term fix limits what Miri keeps. It now preserves only CARGO_* variables, excluding CARGO_*_TOKEN, plus OUT_DIR. The team says the Miri release in the nightly build dated 2026-09-22 no longer has the problem. It adds that the patch may not yet be on nightly for everyone.
The team also scanned GitHub repositories. It found one repository with the issue and seven that do not appear vulnerable but should be cautious. It contacted those maintainers. It also says the scan was probably imperfect, so absence from the list is not proof of safety.
One more detail from the report. Predrag Gruevski of OpenAI reported the issue. OpenAI also supplied the Codex access and credits behind the repository scan, and the Rust team credited the company for that support.
The lesson: the leftovers are the exposure
This shows how secrets escape in practice. A vault protects the secret until a program reads it. Once it sits in the environment, any tool in the job may treat it as ordinary data. The Rust team makes the same point: many tools have no special handling for secrets and assume the whole environment can be written to disk.
The team also warns against relying on any tool to keep environment variables out of target/. Cargo, Miri and Rust do not guarantee it. Build scripts can also place environment data into build outputs. The fix for Miri is sound, but it does not make the pattern safe.
Think of a shared office whiteboard. Wiping one marker's habit of writing passwords on it helps. Keeping passwords away from the room is better.
What leaders should ask their teams
If you run Miri in GitHub Actions, check your setup and clear the cache. The Rust team also suggests rotating any secrets that might have leaked. Rotating is a cheap step next to an investigation with logs that expire.
Then ask broader questions. Which CI jobs can write to a cache that pull requests can read? Do those jobs hold secrets as environment variables for the whole job, or only for the steps that need them? Does any step that touches a cached directory, such as one invoking cargo, have access to tokens it does not use? The Rust team advises scoping secrets to the steps that do not call Miri, and keeping secrets away from jobs that write to public caches.
The practical rule is simple: a cache should hold only what you would be comfortable showing a contributor. If a job needs a secret, keep that job away from the cache.
Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: blog.rust-lang.org.





