Skip to content

fix(dev-server): validate open-url targets - #1416

Draft
dannyhw wants to merge 1 commit into
mainfrom
dannyhw/fix-open-url-validation
Draft

fix(dev-server): validate open-url targets#1416
dannyhw wants to merge 1 commit into
mainfrom
dannyhw/fix-open-url-validation

Conversation

@dannyhw

@dannyhw dannyhw commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • validate /open-url request bodies before invoking the operating-system opener
  • allow only canonical http: and https: URLs
  • reject PowerShell interpolation characters that are unsafe with the pinned open@10
  • add Fastify injection coverage for valid browser links, text bodies, local paths, executable targets, custom schemes, and PowerShell payloads
  • add a patch changeset for @callstack/repack-dev-server

Why

The endpoint passed the request-provided url directly to open(). That package accepts files and executables in addition to URLs, and its Windows implementation interpolates the target into PowerShell. This left the unauthenticated development-server route vulnerable to uncontrolled path/process targets and addresses code-scanning alert #3.

Impact

Normal React Native http: and https: browser links continue to work without configuration or API changes. Invalid bodies, paths, executable targets, and non-browser schemes now receive HTTP 400 and never reach open().

Test plan

  • dev-server Vitest suite (2 files, 26 tests)
  • dev-server TypeScript typecheck
  • Biome check for changed source and tests
  • repository-wide Biome pre-commit hook

What user-facing behavior uses /open-url?

React Native's dev-only openURLInBrowser() helper posts a URL to this endpoint. The React Native New App Screen uses that helper for its Learn & Explore cards: tapping a card such as DevTools opens the documentation in the default browser on the computer running the development server, rather than inside the simulator or device.

The Re.Pack tester app renders its own test dashboard and does not currently include @react-native/new-app-screen or another caller of openURLInBrowser(). Therefore it has no existing on-screen control that reaches /open-url. Pressing j exercises the separate /open-debugger route and is useful only as a general developer-workflow regression check.

Manual tester-app validation

  1. To expose the real user interaction temporarily, add the React Native helper and the tester app's existing button to apps/tester-app/src/App.tsx:

    // @ts-expect-error React Native's dev-only helper does not publish TypeScript types.
    import openURLInBrowser from 'react-native/Libraries/Core/Devtools/openURLInBrowser';
    import { Button } from './ui/Button';

    Then add this section inside SectionContainer:

    <Section
      title="Open URL on development host"
      description="Opens React Native documentation in the host computer's browser"
    >
      <Button
        title="Open React Native docs"
        onPress={() => openURLInBrowser('https://reactnative.dev/')}
      />
    </Section>

    These are local test-only edits and should not be committed.

  2. From the repository root, start the tester-app development server:

    pnpm --filter tester-app start
  3. In a second terminal, launch either platform:

    pnpm --filter tester-app ios
    # or
    pnpm --filter tester-app android
  4. Tap Open React Native docs in the tester app.

    Expected: https://reactnative.dev/ opens in the default browser on the computer running the development server, and the tester app remains running. This exercises the same React Native helper and /open-url request used by New App Screen links.

  5. In the development-server terminal, press r and verify the app reloads, then press j and verify React Native DevTools opens and connects.

  6. Verify a non-browser target is rejected at the endpoint boundary:

    curl -i http://localhost:8081/open-url \
      -H 'Content-Type: application/json' \
      --data '{"url":"file:///tmp/repack-open-url-check"}'

    Expected: HTTP 400 with Invalid URL, with no browser, file, or application opened.

  7. Remove the temporary tester-app edits.

The positive check is intentionally user-facing. The rejected-target check remains direct because no legitimate React Native UI should generate a file, executable, or non-browser URL for this endpoint.

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
repack-website Ready Ready Preview, Comment Jul 27, 2026 10:23pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 44ecf65

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack-dev-server Patch
@callstack/repack Patch
@callstack/repack-plugin-expo-modules Patch
@callstack/repack-plugin-nativewind Patch
@callstack/repack-plugin-reanimated Patch
@callstack/repack-init Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant