Dev News Daily ENDE

Miri copied the whole CI environment into target/, where caches leaked it

The Rust Security Response Team published an advisory on 21 September, written by Manish Goregaokar on behalf of the team, about the interaction between cargo miri and build caching in CI. Miri has to remember which build-relevant environment variables were in effect from one invocation to the next, and the mechanism it used for that wrote a copy of the process environment into the target/ directory. On a laptop nobody notices. In CI, where target/ is one of the first things people cache, it is a copy of every value the job could see — API tokens included.

What turns that into an exposure is the ordinary shape of a GitHub Actions cache. The recommended arrangement lets runs on main write to the cache while pull-request runs may only read from it, precisely so that an outsider cannot poison it. Here the read direction is the one that hurts. Anyone who has had a change merged before can open a pull request, let CI start, pull the cached target/ apart, and then push a second commit on top of the first. GitHub's interface does not show overwritten commits prominently, and both the run logs and the discarded commit are cleared after a few months, so the attempt leaves very little behind.

The short-term patch narrows what Miri preserves to CARGO_* variables, excluding anything matching CARGO_*_TOKEN, plus OUT_DIR. The advisory is explicit that the fix may not have reached nightly at the time of writing, and that the Miri shipping in the 2026-09-22 nightly no longer behaves this way. The team also scanned public repositories and reports one repository actually affected and seven more that did not appear vulnerable but were contacted as a precaution.

If a project matches the pattern — cargo miri in CI, secrets present in the job's environment, target/ cached through actions/cache or swatinem/rust-cache, and the cache reachable by pull requests — the advisory asks for the cache to be cleared and for any secret that could have been captured to be rotated. The quick mitigations offered are disabling the cache for that job, scoping secrets to steps that do not invoke Miri, or turning Miri off until the patched build is available.

Miri copied the whole CI environment into target/, where caches leaked it
Miri copied the whole CI environment into target/, where caches leaked it — Dev News Daily

What it means

The cache is a trust boundary, and almost nobody has drawn it as one. A cache entry is written by one job and read by another that a stranger can trigger. Every byte that lands in a cached directory is, in effect, published to anyone who can open a pull request. That is a property of the plumbing, not of Miri.

Miri is an instance, not the problem. The general assumption underneath is that the process environment is private scratch data a build tool may spill to disk at will, and the advisory says as much: even projects that never run Miri should keep secrets away from any job that can populate a cache readable by pull requests. Cargo itself gives no guarantee that environment variables stay out of target/.

There is a check worth running today, and it takes a minute. Open each workflow and ask, for every job that caches a build directory, whether any step in that job has a secret in env. If the answer is yes, the two do not belong in the same job — regardless of which tool is doing the writing.

Source: https://blog.rust-lang.org/2026/09/21/github-actions-leaking-secrets-when-miri-output-is-cached/