Skip to content

Move /open-stack-frame and /open-url into community-cli-plugin - #59316

Open
huntie wants to merge 1 commit into
mainfrom
pr59316
Open

huntie wants to merge 1 commit into
mainfrom
pr59316

Conversation

@huntie

@huntie huntie commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Context

Migration of the remaining core dev server endpoints from @react-native-community/cli-server-api into core (community-cli-plugin).

Core motivation: These endpoints are critical infra! Most notably the WS /message endpoint, which carries reload and Dev Menu commands from the terminal and other tools.

The intent is to later move most of these again into dev-middleware (shared by CLI and Expo). For now, this stack focuses on decoupling CLI as an initial migration. (I note also that fb-metro-cli probably can't accept moving all of these into dev-middleware just yet.)

This diff

Migrate the /open-stack-frame (used by LogBox, RedBox) and /open-url (used by new-app-screen) routes to core.

Additionally, port the hardening Expo CLI applied to its own /open-stack-frame (expo/expo#44039, expo/expo#45863).

Paired with react-native-community/cli#2875, which removes the CLI's copies.

Net changes

This is a non-breaking change when CLI and react-native are shipped in lockstep.

This diff also tightens behaviour compared to the CLI versions:

  • /open-stack-frame: Validate the posted frame, and only open files that resolves inside the server root or a watch folder.
  • Both routes: Throttle to one launch per 2 seconds, and refuse cross-origin browser requests with the inspector proxy's origin rule.

Notes

  • For GitHub Actions runs on main (until we publish a new CLI beta), the older CLI copy is still mounted and used first (local testing was validated properly).

Changelog:
[General][Changed] - Dev server: Guard /open-stack-frame to only open files inside the project watch folders

Test Plan

yarn jest packages/community-cli-plugin/src/dev-server
yarn flow-check
yarn eslint packages/community-cli-plugin

✅ 25 tests pass: launches with the posted file and line or URL, a relative path, cross-origin requests, malformed bodies, containment (a file outside, a symlink out, a nonexistent file), rejected URL schemes and shell characters, the throttles, a failed browser launch, and a GET passing through. Flow and ESLint clean.

RNTester's Metro with a local cli-server-api carrying react-native-community/cli#2875 linked in, so the plugin serves both routes, and $REACT_EDITOR set to a script that logs each launch:

  • ✅ curl -X POST /open-stack-frame for RNTesterAppShared.js answered 200 OK and the script logged the file. For /etc/hosts: 400, "File is missing or outside the project watch folders".
  • ✅ curl -X POST /open-url with http://localhost:<port>/status answered 200 OK and opened the browser. For file:///etc/passwd: 400.
  • A cross-origin Origin header is answered by the CLI's own guard, mounted first, with its 500.

✅ RNTester on iPhone 18 Pro (iOS 27.0), with this stack: tapping the top frame of the Crash example's LogBox (CrashExample.js:34:26) launched $REACT_EDITOR with CrashExample.js.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 21, 2026
@huntie huntie changed the title Move /open-stack-frame into dev-middleware Move /open-stack-frame and /open-url into community-cli-plugin Oct 29, 2026
@huntie

huntie commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot Please adversarially review this PR for CVE-2025-11953, and comment with your result.

Copilot AI commented Oct 29, 2026

Copy link
Copy Markdown

@copilot Please adversarially review this PR for CVE-2025-11953, and comment with your result.

Review result: I found no CVE-2025-11953 command-injection path in the new plugin handler. It accepts only parsed HTTP(S) URLs and rejects PowerShell expansion characters before calling open (openURLMiddleware.js:87–102); the plugin uses open@^8.4.2, not the vulnerable CLI open@6 invocation. The caveat is middleware order: runDevServer.js:169–173 mounts community middleware first, so until the CLI copy is removed, that handler wins. Ensure the paired CLI version includes its CVE-2025-11953 URL-sanitization fix; this plugin change alone does not protect projects still using an unfixed CLI copy.

@huntie
huntie requested a review from vzaidman October 30, 2026 11:10
@huntie
huntie marked this pull request as ready for review October 30, 2026 11:10
@huntie
huntie added this pull request to stack #59664 October 30, 2026 11:11
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 30, 2026
meta-codesync Bot pushed a commit that referenced this pull request Oct 30, 2026
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. -->

## Summary

Motivated by #59316.

Changelog: [Internal]

## Test Plan

```
yarn prettier --check AGENTS.md
```

✅ Clean. Documentation only.

Differential Revision: D128379539

Pull Request resolved: #59621

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Expo Partner: Expo Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants