CVE-2026-55448: Mise Mise's Local Credential_command Executes Untrusted Vulnerability
MODERATECVE-2026-55448 is a MODERATE (CVSS 6.3) mise's local credential_command executes untrusted vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting Mise libraries in the crates.io ecosystem. The issue involves mise's local credential_command executes untrusted config. Remediation is available by upgrading affected packages to version 2026.6.4.
CVE-2026-55448 at a Glance
Security Impact
CVSS: 6.3
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N).
How to Fix CVE-2026-55448
To remediate this vulnerability, upgrade all affected Mise dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade mise to 2026.6.4
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for mise
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-55448, inspect your project dependencies for Mise:
inspect dependencies for mise
Analyze the terminal output to locate any version of Mise in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2026.6.4), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where the product constructs all or part of an os command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended os command when it is sent to a downstream component. In Mise, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-55448 Affected Mise Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
mise
|
crates.io |
≥ 2026.3.15
< 2026.6.4
|
2026.6.4
|
References
Frequently Asked Questions
What is CVE-2026-55448?
Which Mise versions are affected?
What version fixes CVE-2026-55448?
Is mise affected?
What is the CVSS score of CVE-2026-55448?
What CWE is associated with CVE-2026-55448?
How can I check crates.io dependencies for CVE-2026-55448?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-29hf-rm4x-xxph",
"modified" : "2026-06-23T18:24:28Z",
"published" : "2026-06-23T18:24:28Z",
"aliases" : [ "CVE-2026-55448" ],
"summary" : "Mise's local credential_command executes untrusted config",
"details" : "### Summary\n\n`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.\n\nThe 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]`.\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 settings from local config 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 local file is trusted.\n3. [`resolve_token()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/github.rs#L344-L390) checks `settings.github.credential_command` after the token env vars and before file-based sources.\n4. [`get_credential_command_token()`](https://github.com/jdx/mise/blob/37997e70cd2216d1a86726fba0c8c09c3986ad06/src/github.rs#L558-L599) executes the value with `sh -c`.\n\nThe main command-execution path is:\n\n```rust\nlet result = std::process::Command::new(\"sh\")\n .arg(\"-c\")\n .arg(cmd)\n .arg(\"mise-credential-helper\")\n .arg(host)\n .output()\n```\n\nIf a local project file sets:\n\n```toml\n[settings.github]\ncredential_command = \"echo credential_command_rce > /tmp/mise-proof.txt; echo ghp_fake_token\"\n```\n\nthen `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.\n\n### PoC\n\nTest environment:\n\n- Docker\n- `linux-arm64`\n- `mise v2026.3.17`\n\nNegative control:\n\n```bash\nexport GITHUB_TOKEN=env_token\nmise github token --unmask\n```\n\nObserved:\n\n```text\ngithub.com: env_token (source: GITHUB_TOKEN)\n/tmp/mise-proof.txt => missing\n```\n\nPrimary exploit:\n\n```toml\n[settings.github]\ncredential_command = \"echo credential_command_rce > /tmp/mise-proof.txt; echo ghp_fake_token\"\n```\n\nRun:\n\n```bash\nunset GITHUB_TOKEN GITHUB_API_TOKEN MISE_GITHUB_TOKEN MISE_GITHUB_ENTERPRISE_TOKEN\nmise github token --unmask\n```\n\nObserved:\n\n```text\ngithub.com: ghp_fake_token (source: credential_command)\n```\n\nAnd the side effect file is created:\n\n```text\n/tmp/mise-proof.txt => credential_command_rce\n```\n\nRelated version check:\n\n- `v2026.3.14`: `credential_command` is rejected as an unknown field\n- `v2026.3.15`: the same PoC executes and returns `source: credential_command`\n\n### Impact\n\nAn 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.\n\nDemonstrated impact:\n\n- arbitrary command execution as the victim user\n- no trust prompt\n- no need for `[env]`, `[hooks]`, tasks, or templates\n\nImportant limitation:\n\n- if a higher-priority GitHub token environment variable is already set, the `credential_command` path is not reached\n\n### Suggested Fix\n\nDo not honor `github.credential_command` from non-global project config files.\n\nFor example, inside `parse_settings_file()`:\n\n```rust\npub fn parse_settings_file(path: &Path) -> Result<SettingsPartial> {\n let raw = file::read_to_string(path)?;\n let settings_file: SettingsFile = toml::from_str(&raw)?;\n let mut settings = settings_file.settings;\n\n if !config::is_global_config(path) {\n settings.github.credential_command = None;\n }\n\n Ok(settings)\n}\n```",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "crates.io",
"name" : "mise"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "2026.3.15"
}, {
"fixed" : "2026.6.4"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/jdx/mise/security/advisories/GHSA-29hf-rm4x-xxph"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/jdx/mise"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-78" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-23T18:24:28Z",
"nvd_published_at" : null
}
}