Skip to content

fix: exact own origin for allowedOrigins lists, and open-editor over the network - #5776

Open
alexander-akait wants to merge 2 commits into
mainfrom
fix/origin-and-open-editor-gaps
Open

alexander-akait wants to merge 2 commits into
mainfrom
fix/origin-and-open-editor-gaps

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

I audited the security behavior of main after #5770. The test drove a real browser against a dev server, with a hostile page on another loopback port and the server reached by a LAN address. It found two gaps; this PR closes both. The default setup on localhost behaves exactly as before.

1. allowedOrigins as a list: the page's own origin is now exact

With a list, even [], the page's own origin used to mean its hostname on any port, with localhost, 127.0.0.1 and [::1] counted as one. Explicit mode answers an allowed origin with an echoed Access-Control-Allow-Origin. So any other server's page on localhost could:

  • load the bundle,
  • read it through CORS (including the /webpack-dev-server assets page),
  • and connect to the HMR WebSocket.

It now means the host and port the request reached the server by, exactly. The scheme is not compared, so a proxy that terminates TLS in front of the server still counts. A pretend Host (with a path or credentials) never matches.

  • Pages on other ports must be listed.
  • The injected client is handed the hot token in this mode, so its HMR connection still gets in even when client.webSocketURL points elsewhere.

allowedOrigins is not released yet (#5770). The release PR #5774 includes it, so please merge this one first.

2. /webpack-dev-server/open-editor reached through a network address

Browsers send neither Sec-Fetch-Site nor Origin for a page that is not a secure context, which is any http: page except one on localhost. With the server reached as http://192.168.x.x:8080 (the default host listens on every interface), any page could load /webpack-dev-server/open-editor?fileName=/etc/hostname as an image and launch the editor. The audit reproduced this in both "auto" and list modes.

Such a request must now show where it came from:

  • a same-origin Referer, which the overlay's own fetch sends;
  • or, in list mode, the hot token.

Requests through localhost are let in as before: browsers send Sec-Fetch-Site there, so a header-less request is a non-browser client. invalidate is unchanged (it only triggers a rebuild, and it is used by typing its URL).

Not changed, already tracked in code TODOs (#5775)

  • Under "auto", a page on another loopback port can still connect to the HMR WebSocket. Real setups rely on this (a backend page on another port using HMR). The next major hands the token to every client and requires the exact origin.
  • host defaults to every interface, serveIndex is on, and static.deny is off.

Tests

  • Unit tests for exact matching: port, loopback alias, default port, TLS-terminating proxy, malformed Host.
  • e2e tests: another port and 127.0.0.1 are refused with no ACAO and no HMR; the page's own origin gets no credentials.
  • Open-editor tests through a network address: refused with no page or a foreign Referer; allowed with its own Referer, Sec-Fetch-Site: same-origin, or the token.
  • Full suite run locally. Apart from the sandbox-only failures main also has (IPv6, proxy, overlay snapshots), the only differences were the CLI help snapshots, updated here. harness-server-cleanup hangs in the sandbox on main as well.
  • I re-ran the browser audit: the other-port page is blocked on every path tested in list mode, the editor is no longer launched over the LAN, and the default localhost behavior is unchanged.

Generated by Claude Code

Summary by CodeRabbit

  • Security

    • Strengthened protection when opening the editor from network addresses by validating same-origin requests and page provenance.
    • Tightened allowed-origin matching to the exact host and port, including stricter handling of malformed or mismatched origins.
    • Preserved trusted access for localhost and valid hot-token requests.
  • Documentation

    • Updated allowed-origin configuration guidance and CLI descriptions to reflect exact origin matching and related HMR behavior.

alexander-akait and others added 2 commits October 20, 2026 11:53
…the network

With `allowedOrigins` set, the page's own origin is now the host and port
it reached the server by, exactly, instead of its hostname on any port
with the loopback names counted as one: another server's page on
`localhost` could read the bundles through CORS and receive hot updates.

`/webpack-dev-server/open-editor` reached through a network address now
needs a same-origin `Referer` (or the hot token) when the request carries
neither `Sec-Fetch-Site` nor `Origin`, which a browser omits for any
`http:` page that is not on `localhost`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjuMAuk9o6UazjHzcAQCTA
@coderabbitai

coderabbitai Bot commented Oct 20, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1fca1fcb-120c-414a-8554-ab1112470311
📥 Commits

Reviewing files that changed from the base of the PR and between f62b534 and f6a57ed.

📒 Files selected for processing: 11
  • .changeset/independent-origin-authorization.md
  • .changeset/open-editor-network-csrf.md
  • README.md
  • examples/allowed-origins/README.md
  • lib/Server.js
  • lib/options.check.js
  • lib/options.json
  • test/cli/__snapshots__/basic.test.js.snap.webpack5
  • test/e2e/allowed-origins.test.js
  • test/server/allowed-origins.test.js
  • test/server/host-header-validation.test.js

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Walkthrough

Allowed-origin checks now compare exact hosts and ports, with default-port normalization. The editor-opening endpoint now requires same-origin validation and evidence that the request came from the server’s page. Tests and documentation were updated for these rules.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to f6a57

This change tightens allowed-origin matching and adds protection for the open-editor endpoint. No merge-blocking issue was identified in the supplied review.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies both main changes: exact own-origin matching for allowedOrigins lists and network protection for the open-editor endpoint. It is concise and specific.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files. (6 skipped: 6 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.26027% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.80%. Comparing base (f62b534) to head (f6a57ed).

Files with missing lines Patch % Lines
lib/Server.js 97.26% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5776   +/-   ##
=======================================
  Coverage   95.79%   95.80%           
=======================================
  Files           6        6           
  Lines        5539     5596   +57     
=======================================
+ Hits         5306     5361   +55     
- Misses        233      235    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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