React Native Community CLI Metro Dev Server `/open-url` OS Command Injection (CVE-2025-11953)
by boroeurnprach · 2026-07-06
- Severity
- Critical
- CVE
- CVE-2025-11953
- Category
- network
- Affected product
- @react-native-community/cli / @react-native-community/cli-server-api (Metro Development Server, openURLMiddleware)
- Affected versions
- @react-native-community/cli 4.8.0 – 20.0.0-alpha.2 (fixed in 20.0.0)
- Disclosed
- 2026-07-06
- Patch status
- patched
Tags
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-06 |
| Last Updated | 2026-07-06 |
| Author / Researcher | boroeurnprach |
| CVE / Advisory | CVE-2025-11953 |
| Category | network |
| Severity | Critical |
| CVSS Score | 9.8 (per NVD) |
| Status | Weaponized |
| Tags | react-native, metro, dev-server, cli-server-api, open-url, command-injection, cwe-78, unauthenticated, node.js, python, windows, cross-platform |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | @react-native-community/cli / @react-native-community/cli-server-api (Metro Development Server, openURLMiddleware) |
| Versions Affected | @react-native-community/cli 4.8.0 – 20.0.0-alpha.2 (fixed in 20.0.0) |
| Language / Platform | JavaScript/Node.js (Metro dev server, target); Python 3 (PoC exploit client) |
| Authentication Required | No |
| Network Access Required | Yes |
Summary
The Metro Development Server started by the React Native Community CLI binds to external network interfaces by default and exposes an /open-url HTTP endpoint (implemented by openURLMiddleware in @react-native-community/cli-server-api) that is intended to open a URL/deep-link in a browser or simulator during development. The root cause is that the url field from the client’s JSON POST body is passed through to the OS’s “open” mechanism without validating that it is actually a URL or sanitizing it against shell metacharacters, so the value is effectively executed as an OS command/executable. Because the dev server requires no authentication and listens on all interfaces, any network-adjacent attacker who can reach port 8081 can submit a crafted url value to have the developer’s machine execute arbitrary programs — on Windows this is demonstrated by submitting calc.exe directly as the “URL”, launching Calculator, and the same code path extends to arbitrary shell command injection.
Vulnerability Details
Root Cause
The vulnerable code path is the openURLMiddleware handler shipped in @react-native-community/cli-server-api, mounted by the CLI’s Metro dev server at POST /open-url. The repro server in this PoC mounts the real, unmodified vendored middleware directly:
| |
openURLMiddleware reads the url field from the POST body and passes it to the platform “open” mechanism (e.g. start/cmd.exe on Windows, open/xdg-open via a shell on macOS/Linux) without validating that the value is a well-formed http(s):// URL or an app deep-link, and without shell-escaping it. Since the underlying open call is executed through a shell/command interpreter, the attacker-controlled string is interpreted as a command rather than strictly as a URL argument — on Windows, simply supplying an executable name (calc.exe) as the “URL” is enough to have it launched directly, and the same unsanitized-argument path allows appending arbitrary shell metacharacters for full OS command injection.
Attack Vector
- A developer runs the React Native CLI (
npx react-native startor equivalent), which starts the Metro dev server on port 8081, bound to all interfaces by default (not just localhost). - An unauthenticated attacker on the same network (or with any network path to port 8081) sends a
POST /open-urlrequest with a JSON body{"url": "<attacker-controlled string>"}. - The server’s
openURLMiddlewarepasses the string straight through to the OS-level “open” call with no validation/sanitization. - On Windows, the string is executed as a command/program directly (PoC demonstrates
calc.exelaunching Calculator); on POSIX platforms the same code path is reachable via the shell used to invokeopen/xdg-open, allowing command injection via shell metacharacters in the supplied value. - The command/executable runs with the privileges of the developer’s Metro/Node process — i.e. the developer’s own user account.
Impact
- Unauthenticated remote code execution on any developer machine (or CI runner) with a Metro dev server reachable over the network.
- Full compromise of the developer’s workstation, including access to source code, credentials, SSH/cloud keys, and further lateral movement from the development environment.
- Trivial to weaponize since the endpoint requires zero authentication and the dev server is commonly left running and network-accessible during normal React Native development workflows.
Environment / Lab Setup
Target: Node.js environment with @react-native-community/cli / cli-server-api 4.8.0 - 20.0.0-alpha.2
(repro server: vuln_server.js, mounts the real openURLMiddleware on a bare connect() app, port 8081)
Attacker: Python 3 with `requests` (poc.py for POSIX targets, windows_PoC.py for Windows targets)
Install: npm install (pulls @react-native-community/cli, cli-server-api, metro, connect, etc. per package.json)
Proof of Concept
PoC Script
See
vuln_server.js,poc.py, andwindows_PoC.pyin this folder.
| |
Underlying request made by both PoC scripts against TARGET:8081:
| |
Detection & Indicators of Compromise
Signs of compromise:
- Metro dev server (
node/react-native) process tree showing unexpected child processes it did not itself need to launch /open-urlrequests in dev-server logs originating from non-loopback source IPs- Unexpected outbound network connections or file modifications originating from a developer workstation running
react-native start
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade @react-native-community/cli (and cli-server-api) to version 20.0.0 or later, which fixes the open-url command injection |
| Interim mitigation | Bind the Metro dev server to localhost only (avoid --host 0.0.0.0/exposing port 8081 externally), block port 8081 at the host/network firewall for untrusted networks, and avoid running the dev server on shared/untrusted Wi-Fi |
References
Notes
Mirrored from https://github.com/boroeurnprach/CVE-2025-11953-PoC on 2026-07-06. Note the source repository has since been transferred to a different owner on GitHub; contents mirrored here (vuln_server.js, poc.py, windows_PoC.py, plus supporting package.json/metro.config.js) reflect the state at time of cloning and implement the real React Native Metro dev-server /open-url command-injection PoC as described in the prior-pass verification note.
| |