DEV Community

Cover image for GitHub Actions Cache Can Leak Secrets Through Miri's target/ Directory
soy
soy

Posted on Originally published at media.patentllm.org

GitHub Actions Cache Can Leak Secrets Through Miri's target/ Directory

The Rust Security Response Team disclosed on September 21 that Miri writes every environment variable into its target/ build directory, and that caching target/ in GitHub Actions — a default pattern via actions/cache — can expose those variables to workflows running against pull requests. Any repository running cargo miri with a cached target/ directory and secrets in the same job is affected right now, not hypothetically.

What changed

Miri, the interpreter the Rust project uses to catch undefined behavior that normal compilation misses, stores all environment variables into its target/ output directory as part of how it operates internally. That behavior has existed for a while, but it turned into a disclosed vulnerability once a common CI pattern collided with it: caching target/ between CI runs via actions/cache to speed up builds.

GitHub Actions caches created from a repository's default branch are readable by workflows triggered against pull requests from that same repository — and, depending on workflow configuration, from forks. That means a cache written by a trusted branch build, with secrets sitting inside target/ because Miri put them there, becomes readable to anyone who can open a pull request. The exploit chain needs three things to line up in the same job: cargo miri running with secret environment variables present, the target/ directory from that run getting cached, and a PR-triggered workflow with read access to that cache. Where all three hold, an attacker with pull-request access can pull secrets straight out of the cache — and the disclosure notes they could plausibly cover their tracks afterward by overwriting the offending commits.

The Rust team's own fix narrows what Miri writes into target/ to just CARGO_* variables (with tokens excluded) plus OUT_DIR, cutting off the specific leak path at its source. But the disclosure is explicit that this is a partial fix, not a complete one: it addresses what Miri itself writes, not what any other build step might already be caching, so the advisory pairs the code fix with three CI-configuration changes every affected repository owner needs to apply independently — none of which the Miri patch itself can substitute for.

Who this affects

This affects any repository that runs cargo miri inside GitHub Actions and caches the target/ directory in that same job — a combination common enough that the Rust team treated it as worth a same-day public disclosure rather than a silent patch. It matters most to projects using Miri for CI-gated undefined-behavior checks on crates that also handle deployment secrets, package-registry tokens, or signing credentials somewhere in the same workflow file, since those are exactly the values that end up cached alongside Miri's output.

It does not affect projects that don't run Miri in CI at all, or that already isolate secret-bearing steps into a separate job with no shared cache from the Miri job. Maintainers of forks that submit pull requests to affected upstream repositories aren't at direct risk themselves, but should be aware the read access their PR workflow gets is exactly the access path the advisory describes.

Verdict

This is not a wait-and-see advisory. Any repository matching the affected pattern — cargo miri plus a cached target/ plus secrets in the same job — should treat it as an incident to close today, not a changelog entry to read later. The concrete steps, in order: disable actions/cache for jobs that invoke Miri, move any secret environment variables so they're scoped only to steps that never touch Miri, clear existing caches on the affected repository, and rotate every secret that could plausibly have been cached before this disclosure. Rust's own upstream fix — restricting what Miri writes to target/ — helps going forward but does not retroactively protect a cache that was already poisoned before the patch landed, so clearing and rotating is not optional even after updating.

For repositories that don't run Miri in CI at all, there is nothing to do here beyond confirming that's actually true.

Tracked daily from official release feeds and vendor changelogs. Full archive: https://media.patentllm.org

Top comments (0)