This site is being rebuilt and some pages are out of date. For current details, write to [email protected]. This notice goes away when the rebuild is done.

No analytics unless you allow it, no tracking. This site keeps in your browser the language you pick, the theme, its colour, which site you chose, the currency on the pricing page and that you closed this notice; signing in adds session cookies. The legal page has the details.

Sign in

Radar · Rust · #001 · Week 39 · Sep 21 – 27, 2026

GitHub Actions leaking secrets when Miri output is cached

Worth knowingtooling

What changed
The Rust Security Response Team found that cargo miri stored all environment variables in target/. With GitHub Actions caching target/, a pull request could read secrets from the cache. From the 2026-09-22 nightly, Miri keeps only CARGO_* variables (except CARGO_*_TOKEN) and OUT_DIR.
Production impact
You were exposed if CI runs cargo miri, that step can see secrets as environment variables, the job caches target/ (for example with actions/cache or Swatinem/rust-cache), and pull requests can read that cache. After fixing the job, the advisory says to clear the cache and consider rotating any secrets that may have leaked.
Try it
Find every CI job that runs cargo miri and caches target/: disable the cache for it or scope secrets to steps that do not run Miri, then clear the cache.
Source
blog.rust-lang.org/2026/09/21/github-actions-leaking-secrets-when-miri-output-is-cached/

Understand it, then run it

Miri is a tool that runs your Rust tests in an interpreter to catch undefined behaviour. To do its job it runs several times per test, and it needs to remember some settings between those runs, so it saved the environment variables it saw into files under target/.

The trouble is that it saved all of them. Many CI setups cache target/ to build faster, and pull requests can often read that cache, so a secret such as an API token could end up readable by anyone who can open a pull request. The fixed Miri saves only the variables it needs.

Run it now

Todayrust
// The fix in the Rust security advisory: Miri used to write every environment
// variable it saw to target/, where a cached target/ could hand it to a pull
// request. It now keeps only CARGO_* variables (except CARGO_*_TOKEN) and
// OUT_DIR. This applies both rules to the environment of a typical CI step.
fn kept_after_fix(name: &str) -> bool {
    (name.starts_with("CARGO_") && !name.ends_with("_TOKEN")) || name == "OUT_DIR"
}

fn main() {
    let step_env = [
        "CARGO_PKG_NAME",
        "CARGO_TERM_COLOR",
        "CARGO_REGISTRY_TOKEN",
        "OUT_DIR",
        "GITHUB_TOKEN",
        "AWS_SECRET_ACCESS_KEY",
        "PATH",
    ];
    println!("{:<24} {:<18} {}", "variable", "before the fix", "after the fix");
    for name in step_env {
        let after = if kept_after_fix(name) { "written" } else { "not written" };
        println!("{name:<24} {:<18} {after}", "written");
    }
}

What it printed when we ran it on Rust 1.98.1 (edition 2024)

variable                 before the fix     after the fix
CARGO_PKG_NAME           written            written
CARGO_TERM_COLOR         written            written
CARGO_REGISTRY_TOKEN     written            not written
OUT_DIR                  written            written
GITHUB_TOKEN             written            not written
AWS_SECRET_ACCESS_KEY    written            not written
PATH                     written            not written

Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.

Written by gpt-oss-120b from the linked source · claims checked against the sources · human-reviewed