The React Native CLI vulnerability (CVE‑2025‑11953) puts developer workstations at risk by exposing an OS command injection path through the Metro development server. Affected ranges include @react-native-community/cli and the cli-server-api package from versions 4.8.0 up to 20.0.0‑alpha.2; the fix is available in 20.0.0 and later. Severity is critical (CVSS 9.8). If Metro is reachable from your LAN (or worse, the internet), an unauthenticated attacker can trigger commands on the host running your dev server—full shell command control on Windows and executable launch on macOS/Linux. Patch and lock down Metro now. (jfrog.com)
What actually changed this week—and why it matters
The disclosure on November 3, 2025, highlighted two compounding problems: a command injection bug in the CLI’s server middleware and a default network bind that exposes Metro to external interfaces. The printed console message implied localhost, but the server listened on 0.0.0.0, leaving dev endpoints reachable by anyone on the same network unless you explicitly constrained the host. The upstream fix shipped with the 20.0.0 line. That combination—easy reachability plus a trivial payload—explains the critical score and why teams should treat this as a same‑week remediation. (jfrog.com)
Coverage from security advisories and industry press converged on the same risk picture: unauthenticated network access to Metro, an exploitable POST endpoint, and platform‑specific execution differences (worse on Windows). While there were no confirmed widespread exploitation reports in the first days post‑disclosure, the risk calculus doesn’t hinge on mass exploitation; it hinges on your developers opening Metro on coffee shop Wi‑Fi, guest networks, or misconfigured office VLANs. (infoworld.com)
Who’s actually exposed?
If your developers use the stock React Native CLI to run Metro (npx react‑native start or similar), you’re in scope unless you’ve already upgraded and locked down. Teams using frameworks that don’t rely on Metro as the dev server are typically not impacted, but verify your toolchain—many wrappers still spawn Metro under the hood. The affected code path lives in @react-native-community/cli-server-api and is commonly bundled with matching CLI versions; check both direct and transitive dependencies across repos and templates. (jfrog.com)
Impact differs by platform. On Windows, the injection can lead to arbitrary shell command execution with attacker‑controlled arguments. On macOS and Linux, attackers can run arbitrary executables with limited parameter control. That’s still more than enough to plant persistence, drop malware, or exfiltrate secrets from your dev box if your session is reachable. (jfrog.com)
React Native CLI vulnerability: your 10‑step rapid triage
Here’s the thing—most of the risk disappears once you upgrade and stop binding Metro to the world. Use this playbook across every machine and project:
-
Inventory where Metro runs. Search your org for
react-native start,npx react-native, and package.jsonstartscripts. Don’t forget templates and old prototypes that devs still run locally. -
Confirm affected versions. In each repo, run
npm ls @react-native-community/cli-server-apiandnpm ls @react-native-community/cli. Flag anything from 4.8.0 through 20.0.0‑alpha.2. (jfrog.com) -
Upgrade to the fixed line. Bump @react-native-community/cli and/or @react-native-community/cli-server-api to 20.0.0 or newer. Re‑lock dependencies (npm, pnpm, or Yarn). Verify the lockfile captured the patched versions everywhere, including workspace packages. (jfrog.com)
-
Bind Metro to localhost explicitly. Update your scripts to
react-native start --host 127.0.0.1 --port 8081. This tiny flag eliminates accidental network exposure—even if someone downgrades tooling later. The CLI supports--hostand also offers--httpsif you want TLS for local traffic. (fig.io) -
Keep device debugging working—safely. For Android emulators, use
adb reverse tcp:8081 tcp:8081so the app reaches Metro via loopback. For iOS Simulator you’re already on the host. For physical devices, use a VPN to a private address or a one‑off port‑forward—not a world‑open bind. -
Firewall the port. Block inbound 8081 except from loopback. On macOS, enable the application firewall and deny inbound for your terminal app; on Windows, add an inbound rule to restrict 8081 to 127.0.0.1. On Linux, a simple ufw rule will do.
-
Audit remote dev and Codespaces. If you tunnel or forward the dev server, ensure it’s authenticated and scoped to your account or VPN. Never expose Metro to the public internet.
-
Scan for reachability. From a second machine on the same network, confirm you can’t hit your Metro host:8081. Repeat after upgrades, on every platform your team uses.
-
Harden defaults in templates. In your company RN template, bake in
--host 127.0.0.1, document emulator/device guidance, and include firewall notes so new hires don’t regress your posture. -
Track it like an incident. Assign an owner, set a 72‑hour deadline, and report completion. If you need a turnkey runbook, see our step‑by‑step 72‑hour fix for React Native CLI teams.
Is my production app affected?
No, not directly. This vulnerability targets the development server, not compiled production apps. The risk is to developer machines, secrets, and lateral movement in your network when Metro is running. Still, protecting dev environments protects production indirectly—your CI tokens, package signing keys, and admin cookies live there during the day. (jfrog.com)
How do I know Metro isn’t exposed anymore?
After upgrading and adding --host 127.0.0.1, verify with a port check. On macOS/Linux, lsof -iTCP:8081 -sTCP:LISTEN -n -P should show 127.0.0.1. On Windows, use netstat -ano | findstr 8081 and confirm the local address is 127.0.0.1. Then try connecting from another device on the LAN—connection should fail. The CLI also supports --https and custom certs if you prefer encrypted local traffic. (fig.io)
People also ask
Does Expo change the risk profile?
Expo projects often rely on similar local dev servers. If your workflow ever exposes a packager on your LAN, follow the same principles: bind to loopback, prefer emulator port‑forwarding, and avoid public exposure. Treat this as a policy, not a one‑off patch.
What about Windows developers?
Prioritize Windows hardening first. The exploit path allows full shell command execution with controlled arguments on Windows, which amplifies impact if an attacker can reach your Metro host. Windows Defender + strict inbound firewall rules plus the localhost bind are the fastest wins. (jfrog.com)
Could CI be affected?
Metro shouldn’t be running in CI, but remote dev hosts, self‑hosted runners, or cloud workspaces sometimes expose dev ports for convenience. If you find Metro on shared or internet‑reachable infrastructure, treat that as an incident and lock it down immediately.
A practical framework to harden React Native dev
Use this four‑layer model to reduce the blast radius of the next zero‑day, not just this one:
-
Identity and secrets: Short‑lived tokens, least‑privilege PATs, and token scopes that cannot publish or delete packages from a dev box. With npm specifically, GitHub is revoking classic tokens on November 19, 2025; switch to granular tokens or Trusted Publishing now so a compromised dev machine can’t push to the registry. (github.blog)
-
Network hygiene: Loopback binds by default for local servers, VPN for device testing, and deny‑by‑default host firewalls. Document this in your engineering handbook.
-
Supply chain control: Pin and audit dependencies, use org‑scoped registries, and block unknown publishers. Automated dependency scanning should flag vulnerable transitive packages like cli-server-api immediately.
-
Platform upgrades: Keep your builders current. If you’re compiling iOS on GitHub Actions, the newly GA M2 macOS runners improve performance and let you rotate ephemeral machines faster—good for security and velocity. (github.blog)
Data you can bring to your security review
Dates and versions matter for audit trails. CVE‑2025‑11953 was published on November 3, 2025. The affected range spans 4.8.0 through 20.0.0‑alpha.2 of the React Native Community CLI server API, with fixes in 20.0.0 and later. The bug combines a reachable dev server (binding to external interfaces by default) and a POST endpoint that passes user input to an unsafe OS‑level open routine. That’s the root cause behind the critical severity. (cve.li)
Multiple vendors and outlets corroborate the risk profile—unauthenticated network access, Windows execution with full parameter control, and executable launch on Unix‑like systems. Treat developer networks as production‑adjacent and control ingress accordingly. (infoworld.com)
Step‑by‑step: update, harden, and verify
Let’s get practical. Take one repo as a template and propagate:
1) Update dependencies—bump @react-native-community/cli and @react-native-community/cli-server-api to 20.0.0 or newer. Run your package manager’s dedupe and lockfile update, then rebuild. (jfrog.com)
2) Lock down your scripts—in package.json, set "start": "react-native start --host 127.0.0.1 --port 8081". Document emulator port‑forwarding so devs don’t remove the flag “to make it work on a phone.” (fig.io)
3) Firewall rules—create a shared doc (or policy) with platform‑specific steps to restrict inbound 8081 and similar dev ports. Validate with a second device and keep screenshots for compliance.
4) Template and scaffold—update your internal RN template. While you’re there, embed a short “Dev Networking” section covering loopback binds, emulator addresses, and safe device testing.
5) Rollout logistics—don’t YOLO this change. Submit a single PR per repo, assign reviewers from mobile and security, and stage by squad to keep feedback tight.
Related work you should schedule this month
Supply chain risk is not one bug deep. npm is permanently revoking classic tokens on November 19, 2025. If your React Native libraries publish to npm—manually or via CI—plan the cutover to granular tokens or Trusted Publishing and check your org’s 2FA posture. We’ve published hands‑on guides if you need a checklist for CI/CD cutovers and last‑mile fixes: start with the CI/CD cutover guide for npm tokens and the deeper last‑mile playbook. (github.blog)
Also worth a glance: GitHub Actions’ November updates include GA M2 macOS runners and higher limits for reusable workflows—useful if your mobile builds regularly queue. Faster, ephemeral macOS capacity helps contain risk and speed feedback loops for patches like this. See our take on the broader Actions changes here: New Limits, M2 runners, and Copilot changes. (github.blog)
What to do next (this week)
-
Ship the upgrade to CLI 20.0.0+ across all RN repos and templates.
-
Enforce
--host 127.0.0.1in start scripts and docs; block inbound 8081 at the OS firewall. -
Test from a second machine—verify Metro is unreachable on your LAN.
-
Review remote dev setups (Codespaces, self‑hosted runners, cloud VMs) for accidental exposure.
-
Schedule an npm token audit before November 19 for any RN packages you publish.
Zooming out
This incident is a reminder that “it’s only a dev server” is a dangerous assumption. Developer laptops are where company secrets live during active work, and one misbound port can be enough to pivot. The fix is straightforward: patch the CLI, bind Metro to localhost, and make it a template default. Pair that with sane token policies and modern build runners, and you’ll turn a frantic week into a durable security baseline.
If you want help reviewing your mobile dev posture or templating a hardened RN starter, reach out via our engineering services overview or browse recent implementation playbooks on our blog. For hands‑on support, our team is one message away on the contact page.
