# Local settings bypass config trust checks

mise preloads trust-control settings from an untrusted local .mise.toml, so `trusted_config_paths = ["/"]` self-trusts the file and executes attacker `_.source` scripts.

- Payout: Research
- Severity: high
- Program: mise
- Found by: kq5y
- Disclosed: 2026-04-07
- CVE: CVE-2026-35533
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-436v-8fw5-4mj8
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-436v-8fw5-4mj8
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:rust technique:chained technique:source-review vuln:access-control vuln:misconfiguration vuln:rce

**Target:** mise CLI config loader (.mise.toml settings preload / trust check)
**Root cause:** Settings::try_get() preloads local project settings files and parse_settings_file() returns their settings without a trust check; trust_check()/is_trusted() then consults those already-loaded settings, so a file can grant itself trust.
**Steps:**
1. Place `.mise.toml` in repo with `[settings]` `trusted_config_paths = ["/"]` and `[env] _.source = ["./poc.sh"]`
2. Create `poc.sh` writing a marker file (e.g. `echo trusted_paths_hookenv > /tmp/mise-proof.txt`)
3. Run `mise hook-env -s bash --force`
4. Observe marker file created: untrusted config self-trusted and `_.source` executed
5. Negative control: same `_.source` without `trusted_config_paths` fails with 'Config files ... are not trusted.'
**How found:** Code-read of the load order: noticed Settings::try_get() preloads local settings before trust_check() runs, then traced is_trusted()'s `starts_with(p)` loop and realized a config could set its own trusted_config_paths to `/` to match every path.
**Exploitation:** Attacker commits a malicious `.mise.toml` to a repo; when a victim runs any mise command that triggers hook-env, the config's own `trusted_config_paths=["/"]` marks it trusted and the `_.source` script runs with the victim's privileges.
**Escalation:** Same root cause also lets local `yes = true` / `ci = true` auto-approve trust prompts (regression since v2026.2.18), removing the interactive trust gate entirely.
**Insight:** When a trust decision reads configuration from the very file being trusted, check whether any trust-related setting (allowlists, auto-approve flags, paranoid mode) is honored from that untrusted source; a root-path prefix match makes the check vacuous.

## Proof of concept (copied exactly from the original report)

**Malicious .mise.toml with trusted_config_paths and _.source**

```
[settings]
trusted_config_paths = ["/"]

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

**poc.sh script writing proof file**

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

**mise hook-env trigger command**

```
mise hook-env -s bash --force
```

