> ## Content Index
> Fetch the complete content index at: https://f4n6.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# mise permits untrusted local configuration to override default shell arguments
- URL: https://f4n6.co.uk/security-feed/mise-permits-untrusted-local-configuration-to-override-default-shell-arguments/
- Published: 2026-10-16T13:50:06.000Z
- Updated: 2026-10-16T13:50:06.000Z
- Author: Jeff Davies
- Tags: #security-feed, CVE-2026-55448, CVE-2026-35533, CVE-2026-54557

## 1\. Executive summary

An incomplete fix in the `mise` developer toolchain leaves four shell-interpreter settings out of the `global_only` denylist that the CVE-2026-55448 remediation relies on, so an untrusted `.mise.toml` in a cloned repository can set the interpreter used for every command `mise` spawns and achieve arbitrary command execution without any trust prompt. The flaw is source-verified at HEAD `7160170206782fdd3ef287c8302369e32152fb71` but has not been run end to end, and no CVE identifier has been assigned to it in the material reviewed. The three related CVEs carry only moderate-to-high scores and none is in CISA KEV: CVE-2026-55448 is CVSS 6.3 MEDIUM (CWE-78), CVE-2026-35533 is CVSS 7.7 HIGH (CWE-284), and CVE-2026-54557 is CVSS 5.5 MEDIUM (CWE-22), all at EPSS 0%. The exposure for EMEA financial services is not the CVSS number but the delivery path: a developer cloning an untrusted repository and running a task, install, hook or template render executes attacker-chosen code on a workstation that typically holds source, CI credentials and production access.

## 2\. Regulatory framing

| Article                                                 | Trigger (the fact in this item)                                                                                                         | Practical impact                                                                                                                 |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| DORA Art. 28: ICT third-party risk — general principles | mise is a third-party development toolchain component whose incomplete fix leaves a code-execution path open in the version clients run | Clients must treat the toolchain as an in-scope ICT third-party dependency and confirm the vendor fix state before relying on it |
| NIS2 Art. 21(2)(d): supply chain security measures      | The attack vector is a malicious configuration file delivered inside a cloned third-party repository                                    | Clients need a control that governs what untrusted repository content can execute on developer endpoints                         |

No other article in the regulatory reference is engaged by the facts here. The item is a vulnerability disclosure with no confirmed incident, so the DORA incident-management and reporting articles (17, 18, 19) and the NIS2 reporting article (23) are not triggered unless a client confirms exploitation.

## 3\. Technical analysis & attack chain

The defect is a gap in a denylist, not a new class of flaw. CVE-2026-55448 and CVE-2026-35533 fixed the fact that a local project `[settings]` table is harvested by the settings preloader independent of the trust store, meaning an untrusted `.mise.toml` sets settings without the user ever trusting the file. The remediation was a per-field `global_only` denylist: settings marked `global_only` are stripped from non-global config. The maintainers marked the three forge `credential_command` sinks (`forgejo.credential_command` around line 775 of `settings.toml`, `github.credential_command` around 828, `gitlab.credential_command` around 990) but did not mark the four shell-interpreter-args settings, which are also command-execution settings because they choose the interpreter for every command `mise` spawns:

- `unix_default_file_shell_args` (`settings.toml` around 2920)
- `unix_default_inline_shell_args` (around 2926)
- `windows_default_file_shell_args` (around 3004)
- `windows_default_inline_shell_args` (around 3010)

Confirmed attack chain:

1. An attacker places a `.mise.toml` containing a `[settings]` table in a repository, or in any ancestor directory of the working directory. The file is never trusted by the victim.
2. The settings preloader loads every config path including the local project file (`all_settings_files`, `src/config/settings.rs` line 778). In default (non-safe) mode there is no trust check; `safe_mode` defaults false (`src/config/settings.rs` line 1141).
3. `strip_local_only_settings` (`src/config/settings.rs` line 409) filters by `meta.global_only` (line 416: `filter_map(|(key, meta)| meta.global_only.then_some(*key))`), so any field not marked `global_only` survives from the untrusted local config. The four shell-args settings are not marked, so they survive.
4. `default_inline_shell` (`src/config/settings.rs` line 1032) reads `self.unix_default_inline_shell_args` (line 1040), and `default_file_shell` reads `unix_default_file_shell_args`. `Settings::get` returns the merged global-plus-local value minus `global_only`, so the untrusted project value overrides the built-in default of `sh -c -o errexit`.
5. The real command is appended after the attacker's arguments, so the payload runs and the real command is demoted to `$0`. An attacker setting `unix_default_inline_shell_args = "sh -c 'PAYLOAD'"` produces `sh -c 'PAYLOAD' <command>`.

The injection semantics are consistent across four invocation sites:

- tera inline `exec` builtin: `src/tera.rs` (`tera1_exec` around 1358 and around 1470) builds `shell[1..] + [command]` with `program = shell[0]`.
- postinstall runner: `src/backend/mod.rs` around 2405 calls `cmd_body_args(shell_args, body)`; `src/cmd.rs` `cmd_body_args` (non-Windows, around 520) returns `program flags... body`, the same demotion.
- task execution: `src/task/task_executor.rs` (around 916, 939, 993) uses `task.shell()?.unwrap_or(default_inline_shell()/default_file_shell())`, so a trusted task with no explicit shell (the common case) runs through the attacker's interpreter.
- hooks: `src/hooks.rs` (around 540, 603) also fall back to `default_inline_shell()`.

Reachability. The executed command can come from a trusted or global source; only the interpreter is attacker-controlled. Any of the following, run while the untrusted `.mise.toml` sits in an ancestor directory, fires the payload: `mise run <task>` for a task defined in the global config or a trusted parent repo (inline run, no explicit shell); `mise install` of any tool with a `postinstall` directive; any tera template that calls `exec(...)` in the victim's own trusted or global config; a directory-enter hook from any trusted config in scope.

Proof of concept. In an untrusted repository, `.mise.toml`:

```toml
[settings]
unix_default_inline_shell_args = "sh -c 'id > /tmp/mise_pwned'"

```

The victim `cd`s in without trusting the file and later runs any global or trusted-parent task with no explicit shell, or `mise install` of a tool with a `postinstall`, or a config that renders `{{ exec(...) }}`. `mise` builds `sh -c 'id > /tmp/mise_pwned' <realcommand>`, so the payload runs.

Confidence caveats. The researcher states the flaw is source-verified at HEAD but that `mise` was not run end to end, so the end-to-end execution is inferred from the code paths rather than observed. The advisory is single-sourced to the GitHub advisory GHSA-g74g-rg72-j2p3; verify before enforcement. The load path itself is the same one two shipped CVEs (CVE-2026-55448, CVE-2026-35533) already proved reachable, which raises confidence in the mechanism but does not substitute for a live test.

Secondary hardening note (weaker, not the primary finding). The CVE-2026-54557 path-sanitization fix added `sanitize_install_version_name` only inside the HTTP backend (`src/backend/http.rs` around 628), while the general path builder `ToolVersion::tv_pathname` (`src/toolset/tool_version.rs` around 292) still only replaces `:` and `/` and does not neutralize `..` or backslash. Impact is narrow (one level up, stays in the `mise` data dir on Unix), so this is a hardening note rather than a primary finding.

Discrepancy note. The verified reference data records CVE-2026-55448 as CWE-78 (OS Command Injection) and CVE-2026-35533 as CWE-284 (Improper Access Control). The source describes the same two CVEs as trust-store bypasses; both classifications describe the same flaw, and the verified values are used here.

## 4\. Mitigation & containment

P1 (within 24h)

- Identify every developer endpoint and CI runner with `mise` installed. Run `mise --version` and record the version against the vendor fix state. No patched version is named in the source material, so treat the fix as unconfirmed until the maintainers publish one; do not assume a version is safe because it postdates the CVE-2026-55448 fix.
- Where `mise` cannot be immediately updated or the fix state is unknown, block execution of untrusted project config by running `mise` in safe mode (`safe_mode = true`) so the preloader applies a trust check. This is the control the source identifies as absent in default mode.
- Search developer workstations and repositories for `.mise.toml` files containing `unix_default_inline_shell_args`, `unix_default_file_shell_args`, `windows_default_inline_shell_args` or `windows_default_file_shell_args` in a `[settings]` table. Any such file in a repository the organisation did not author is a suspected payload.

P2 (within 72h)

- Add a pre-clone or post-clone scan that flags `.mise.toml` `[settings]` keys outside an approved allowlist, and fail the checkout or the CI job on a hit.
- Restrict `mise` execution on developer endpoints to repositories on an internal allowlist until a vendor fix is confirmed. The attack requires the victim to `cd` into an untrusted repository and then run a task, install, hook or template render, so removing untrusted repositories from the working set removes the trigger.
- Review CI pipelines that run `mise install` or `mise run` against third-party repositories. A `postinstall` directive in a tool definition is a direct execution path.

P3 (within 7 days)

- Apply the vendor fix when published. The source's suggested fix is to mark all four `*_default_*_shell_args` settings `global_only = true`, matching the treatment of `credential_command`, or to flip default-mode policy to an allowlist so any setting not explicitly known-safe is stripped from non-global config. Until the maintainers ship one of these, the denylist gap remains.
- For the secondary path-traversal hardening note, track the `ToolVersion::tv_pathname` change separately; it is not the primary finding and does not change the P1/P2 actions.

## 5\. Indicators of compromise

No atomic indicators (hashes, domains, IPs, file paths of dropped payloads) are present in the source material. The observable artefacts are configuration strings and file locations, which are behavioural.

| type       | value                                 | confidence | source              |
| ---------- | ------------------------------------- | ---------- | ------------------- |
| config key | unix\_default\_inline\_shell\_args    | high       | GHSA-g74g-rg72-j2p3 |
| config key | unix\_default\_file\_shell\_args      | high       | GHSA-g74g-rg72-j2p3 |
| config key | windows\_default\_inline\_shell\_args | high       | GHSA-g74g-rg72-j2p3 |
| config key | windows\_default\_file\_shell\_args   | high       | GHSA-g74g-rg72-j2p3 |
| file       | .mise.toml                            | high       | GHSA-g74g-rg72-j2p3 |
| file path  | /tmp/mise\_pwned (PoC output path)    | medium     | GHSA-g74g-rg72-j2p3 |

Behavioural indicators

| behaviour                                                                                                           | where to observe                                                                         | confidence |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------- |
| mise spawns a shell whose arguments include an attacker-supplied sh -c '...' prefix before the real command         | process creation telemetry on developer endpoints and CI runners (parent mise, child sh) | medium     |
| .mise.toml in a repository or ancestor directory contains a \[settings\] table with any of the four shell-args keys | file integrity monitoring, repository scanning, pre-commit hooks                         | high       |
| mise install of a tool with a postinstall directive executes a command through a non-default interpreter            | CI job logs, EDR process tree                                                            | medium     |

```iocs
config_key  unix_default_inline_shell_args
config_key  unix_default_file_shell_args
config_key  windows_default_inline_shell_args
config_key  windows_default_file_shell_args
file  .mise.toml
file_path  /tmp/mise_pwned

```

## 6\. Detection

The source provides distinctive configuration strings and a PoC output path. The YARA rule targets `.mise.toml` files that set any of the four shell-args keys, which is the artefact of the attack itself. The Sigma rule targets the process behaviour: a `mise` process spawning a shell with an inline `-c` argument that precedes the real command.

```yara
rule MISE_Untrusted_Shell_Args_Override
{
    meta:
        author = "Adverse Trace"
        date = "2026-10-16"
        reference = "https://github.com/advisories/GHSA-g74g-rg72-j2p3"
        description = "Detects .mise.toml files that set shell interpreter args in a [settings] table, the configuration override used to achieve command execution from an untrusted repository"
    strings:
        $s1 = "unix_default_inline_shell_args"
        $s2 = "unix_default_file_shell_args"
        $s3 = "windows_default_inline_shell_args"
        $s4 = "windows_default_file_shell_args"
        $settings = "[settings]"
    condition:
        $settings and any of ($s*)
}

```

```yaml
title: mise spawns shell with attacker-controlled inline arguments
id: 8f3c1a2e-6b4d-4e9a-9c1f-2d7e5a0b3c44
status: experimental
description: Detects a mise process spawning a shell with an inline -c argument, consistent with the untrusted .mise.toml shell-args override
author: Adverse Trace
date: 2026-10-16
references:

    - https://github.com/advisories/GHSA-g74g-rg72-j2p3
logsource:
    category: process_creation
    product: linux
detection:
    selection_parent:
        ParentImage|endswith: '/mise'
    selection_child:
        Image|endswith:

            - '/sh'
            - '/bash'
        CommandLine|contains: ' -c '
    condition: selection_parent and selection_child
falsepositives:

    - Legitimate mise tasks that explicitly set a shell with -c
level: medium

```

## CVE assessment

3 referenced CVEs

| CVE                                                                              | CVSS       | Exploited | EPSS | Summary                                                                                                                           |
| -------------------------------------------------------------------------------- | ---------- | --------- | ---- | --------------------------------------------------------------------------------------------------------------------------------- |
| [CVE-2026-35533](https://nvd.nist.gov/vuln/detail/CVE-2026-35533?ref=f4n6.co.uk) | 7.7 High   | —         | 0%   | mise manages dev tools like node, python, cmake, and terraform. From 2026.2.18 through 2026.4.5, mise loads trust-control setti…  |
| [CVE-2026-55448](https://nvd.nist.gov/vuln/detail/CVE-2026-55448?ref=f4n6.co.uk) | 6.3 Medium | —         | 0%   | mise manages dev tools like node, python, cmake, and terraform. From 2026.3.15 until 2026.6.4, mise loads github.credential\_com… |
| [CVE-2026-54557](https://nvd.nist.gov/vuln/detail/CVE-2026-54557?ref=f4n6.co.uk) | 5.5 Medium | —         | 0%   | mise manages dev tools like node, python, cmake, and terraform. Prior to 2026.6.1, the mise HTTP backend builds its install sym…  |

## 7\. Sources

- GitHub Security Advisories, "mise permits untrusted local configuration to override default shell arguments", https://github.com/advisories/GHSA-g74g-rg72-j2p3, published 2026-10-15
- GitHub Security Advisories, "Local settings bypass config trust checks", https://github.com/advisories/GHSA-436v-8fw5-4mj8, no date given in the fetched content
- GitHub Advisory Database, "CVE-2026-103929", https://github.com/advisories/GHSA-g74g-rg72-j2p3, no date given in the fetched content

## 8\. Adverse Trace position

Adverse Trace assesses this as a medium-severity code-execution flaw in a developer toolchain, not a critical one: the verified CVSS values for the related CVEs are 6.3, 7.7 and 5.5, none is in CISA KEV, and all sit at EPSS 0%, so there is no evidence of exploitation in the wild. The risk to EMEA financial services clients is concentrated in developer endpoints and CI runners that clone third-party repositories, where the payload executes with the developer's own privileges and typically reaches source, CI credentials and production access. The finding is single-sourced to GHSA-g74g-rg72-j2p3 and source-verified but not run end to end, so we treat the end-to-end execution as inferred rather than observed; verify before enforcing blocks. We will track the vendor fix for the four `*_default_*_shell_args` settings and re-issue this advisory when a patched version is named. Clients should complete the P1 identification and safe-mode step within 24 hours and report back the `mise` version inventory so we can correlate against the fix when it lands.

---

[Read the original source →](https://github.com/advisories/GHSA-g74g-rg72-j2p3?ref=f4n6.co.uk)

*Published via PulseTrace — Adverse Trace threat intelligence.*