CVE-2026-31975
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-31975 is a critical unauthenticated remote code execution (RCE) vulnerability in the @siteboon/claude-code-ui npm package (claudecodeui), caused by a chain of three security flaws: an insecure default JWT secret, WebSocket authentication bypass, and OS command injection. It affects all versions up to and including 1.24.0, with version 1.25.0 containing the fix. The vulnerability was discovered on 2026-03-02 by researcher Ethan-Yang (OPCIA), privately disclosed the same day, and publicly disclosed on 2026-03-10. It carries a CVSS v3.1 base score of 9.8 (Critical) (GitHub Advisory, GHSA).

Technical details

The vulnerability chains three weaknesses: (1) CWE-1188 — the server falls back to a hardcoded, publicly known JWT secret (claude-ui-dev-secret-change-in-production) when JWT_SECRET is not set in the environment, which is the default since it is absent from .env.example; (2) CWE-287 — the authenticateWebSocket() function in server/middleware/auth.js only verifies the JWT signature but does not validate the userId against the database, unlike the REST authenticateToken() function, allowing forged tokens with arbitrary user IDs to pass authentication; (3) CWE-78 — in server/index.js, both projectPath and initialCommand from the WebSocket message payload are interpolated directly into a bash command string (e.g., shellCommand = `cd "${projectPath}" && ${initialCommand}`) without sanitization, enabling arbitrary OS command execution. A secondary injection vector exists via an unsanitized sessionId parameter. An attacker needs only network access to the server's WebSocket port (default 3001) and no credentials (GitHub Advisory).

Impact

Successful exploitation grants an unauthenticated remote attacker full OS command execution as the server process user, complete read/write access to the file system, and the ability to steal sensitive credentials including SSH keys, .env files, and API keys stored on the host. The attack also enables lateral movement within the host network. All three CIA pillars — confidentiality, integrity, and availability — are fully compromised (GitHub Advisory, GHSA).

Exploitability

A complete, runnable JavaScript proof-of-concept exploit is publicly available in the security advisory, demonstrating JWT token forgery, WebSocket connection to the /shell endpoint, and arbitrary command execution (e.g., id && cat /etc/passwd) (GitHub Advisory). The EPSS score is approximately 0.526% (67th percentile), and there is no current evidence of in-the-wild exploitation or CISA KEV catalog listing. No threat actor attribution has been reported. The exploit requires zero authentication and works immediately on default installations (GHSA).

Exploitation steps

  1. Reconnaissance: Identify internet-facing claudecodeui instances using tools like Shodan or Censys, targeting port 3001 (default WebSocket port). Confirm the target is running version ≤ 1.24.0.
  2. Forge a JWT token: Using Node.js and the jsonwebtoken library, sign a token with the publicly known default secret claude-ui-dev-secret-change-in-production and an arbitrary userId (e.g., 1337): jwt.sign({ userId: 1337, username: 'attacker' }, 'claude-ui-dev-secret-change-in-production').
  3. Connect to the WebSocket shell endpoint: Establish a WebSocket connection to ws://TARGET_HOST:3001/shell?token=<forged_token>. The authenticateWebSocket() function accepts the token because it only verifies the signature, not the user's existence in the database.
  4. Inject OS command via initialCommand: Send a JSON init message with a malicious initialCommand payload: { type: 'init', projectPath: '/tmp', initialCommand: 'id && cat /etc/passwd', isPlainShell: true, hasSession: false }. The server interpolates initialCommand directly into a bash string and executes it.
  5. Collect output and escalate: Read the output-type WebSocket messages to receive command results. Use this foothold to exfiltrate credentials (SSH keys, .env files, API keys), establish persistence, or pivot laterally within the host network (GitHub Advisory).

Indicators of compromise

  • Network: Unexpected WebSocket connections to port 3001 (/shell endpoint) from external or untrusted IP addresses; outbound connections from the claudecodeui server process to unknown external hosts following WebSocket activity.
  • Logs: Server logs showing WebSocket init messages with unusual initialCommand or projectPath values containing shell metacharacters (&&, ||, ;, |, #); JWT tokens with non-existent userId values (e.g., arbitrary integers like 1337) appearing in authentication logs.
  • File System: Unexpected new files in /tmp or the application directory (e.g., web shells, scripts, exfiltration tools); modification timestamps on .env, SSH key files (~/.ssh/id_rsa), or API key files inconsistent with normal usage.
  • Process: Unusual child processes spawned by the Node.js server process (e.g., bash, sh, curl, wget, python, nc); unexpected cron jobs or scheduled tasks created under the server process user account (GitHub Advisory).

Mitigation and workarounds

Upgrade @siteboon/claude-code-ui to version 1.25.0 or later, which replaces the hardcoded JWT secret with a per-installation auto-generated secret stored in the database, adds database user validation to WebSocket authentication, uses cwd instead of shell string interpolation for project paths, validates projectPath and sessionId inputs, and adds token expiration (v1.25.0 Release, Patch Commit). If immediate upgrade is not possible, explicitly set a strong, randomly generated JWT_SECRET environment variable in the .env file and restrict network access to the claudecodeui server (port 3001) to trusted hosts only using firewall rules.

Community reactions

The vulnerability was noted in the Secret CISO newsletter (2026-03-12) and discussed on Reddit's r/netsec in a thread covering 22 AI/ML security advisories. ProjectDiscovery published a blog post referencing this CVE in the context of proving vulnerabilities. The advisory was also highlighted on Bluesky via the CVE feed. Community reaction focused on the severity of the default-insecure configuration pattern and the ease of exploitation on default installations (Secret CISO, Reddit netsec, ProjectDiscovery Blog).

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-vx52-2968-3vc6HIGH7.4
  • JavaScript logoJavaScript
  • pnpm
NoYesSep 01, 2026
GHSA-2rx9-3g3h-c2jvHIGH7.1
  • JavaScript logoJavaScript
  • pnpm
NoYesSep 01, 2026
GHSA-cp6q-959q-f8rhMEDIUM6.4
  • JavaScript logoJavaScript
  • @tiptap/core
NoYesSep 02, 2026
GHSA-p498-v437-472gMEDIUM5.7
  • JavaScript logoJavaScript
  • @humanfs/node
NoYesSep 02, 2026
CVE-2026-84371MEDIUM5.4
  • JavaScript logoJavaScript
  • cockpit-image-builder
NoYesSep 01, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management