Skip to content

feat: add allowedOrigins option - #5770

Open
bjohansebas wants to merge 14 commits into
mainfrom
fix/allowed-origins
Open

bjohansebas wants to merge 14 commits into
mainfrom
fix/allowed-origins

Conversation

@bjohansebas

@bjohansebas bjohansebas commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Add devServer.allowedOrigins to say which pages may use the dev server: its HTTP endpoints, hot module replacement (WebSocket or Server-Sent Events), proxied WebSockets and the internal endpoints. It is separate from allowedHosts, which checks the Host header (DNS rebinding).

Non-breaking. Nothing changes until the option is set.

  • "auto" (default): the rules derived from allowedHosts, exactly as before. main's own security tests (allowed-hosts, cross-origin-request, event-source, options-middleware, proxy-web-socket-origin, web-socket-server-url, proxy-option) are left unchanged and pass. Under "auto", two settings still open every origin, as they always have: allowedHosts: "all", and an Access-Control-Allow-Origin: * entry in headers (which turns off Cross-Origin-Resource-Policy). Both now print a deprecation warning.
  • A list: the page's own hostname (any port, with loopback names counted as one, as before) plus the listed origins, whatever allowedHosts says.
    • Listed origins get Access-Control-Allow-Origin, Access-Control-Allow-Credentials and Vary: Origin, and their preflight requests get the method, headers and Private Network Access they ask for.
    • A plain <script> or <img> without crossorigin is allowed by the page's Referer, and gets Cross-Origin-Resource-Policy: cross-origin.
    • A cross-site no-cors load from any other page, and a request with any other Origin, gets 403.
  • "all": every origin, with Access-Control-Allow-Origin: *; the Host check stays on.

One internal rule now serves ordinary requests, proxied WebSocket upgrades, hot clients and the open-editor/invalidate endpoints.

Hot token (as in Vite). Once allowedOrigins is set, the injected client is handed a per-run token. A hot client that carries it may connect from an origin the server does not otherwise know, such as a proxy's or a tunnel's. It never replaces the Host check. This uses hot.token: { required: false } from webpack-dev-middleware 8.5.0 (webpack/webpack-dev-middleware#2486), which is now the minimum (^8.5.0). Under "auto" there is no token, so the socket URL and who it lets in are exactly as before. A TODO makes it unconditional in the next major.

static.deny. Off by default.

  • true refuses .env, .env.*, *.{crt,pem,key,p12,pfx,cer,der}, .npmrc, .yarnrc.yml and .git in a static directory with 403, and leaves them out of directory listings.
  • A list of patterns (*, ?, {a,b}) refuses those instead.
  • Matching is per path segment and case-insensitive, after decoding. On Windows it also catches : (alternate data streams) and trailing dots and spaces.

Next major (TODOs in code).

  • Drop "auto" and default allowedOrigins to [].
  • allowedHosts and headers stop granting origins, and the deprecations and legacy checks are removed.
  • client.webSocketURL.hostname stops being an allowed host.
  • static.deny defaults to true.

Docs: a README "Security" section (allowedOrigins, static.deny), the rewritten examples/allowed-origins, and a minor changeset.

Tests:

  • New: test/server/allowed-origins.test.js, test/server/allowed-origins-deprecation.test.js, test/e2e/allowed-origins.test.js (HTTP, HMR, endpoints, a real browser loading a plain script from a listed and an unlisted page, the token), test/e2e/static-deny.test.js.
  • Updated: validation and CLI cases and snapshots.
  • Full suite, compared with main in the same sandbox: no new failures; the remaining 51 are the same set as main (IPv6, proxy 403, a non-local IP).

https://claude.ai/code/session_01UjuMAuk9o6UazjHzcAQCTA


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added allowedOrigins settings to control which website origins can access the development server, including options to use existing host rules, allow specified origins, or allow all origins while retaining Host checks.
    • Added static.deny to block sensitive files with a 403 response and hide them from directory listings, with support for custom patterns.
  • Documentation
    • Added configuration guidance, CLI options, and examples for origin access and static-file blocking.
  • Bug Fixes
    • Improved cross-origin requests and hot-reload connections for pages served from permitted origins.

@changeset-bot

changeset-bot Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3d3355d

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

This PR includes changesets to release 1 package
Name Type
webpack-dev-server Minor

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

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: 5e47ace0-fe65-4032-a202-d409bfcdfb8e
📥 Commits

Reviewing files that changed from the base of the PR and between 8ba3bd2 and 3d3355d.

⛔ Files ignored due to path filters: 1
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing: 7
  • .changeset/independent-origin-authorization.md
  • README.md
  • examples/allowed-origins/README.md
  • lib/hotOptions.js
  • package.json
  • test/e2e/allowed-origins.test.js
  • test/hot-options.test.js
🚧 Files skipped from review as they are similar to previous changes: 2
  • .changeset/independent-origin-authorization.md
  • examples/allowed-origins/README.md

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

The server adds allowedOrigins, defaulting to "auto", and applies origin checks to requests, endpoints, hot clients, and proxied WebSocket upgrades. Explicit origin settings add CORS and resource-policy handling, while a middleware token can authorize injected hot clients. Static options add deny patterns that return 403 for matching GET and HEAD requests and omit denied names from directory listings. The change also adds option validation, CLI support, tests, documentation, and an example, and updates the webpack-dev-middleware version range.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 3d335

No merge-blocking issue was identified in the reviewed origin authorization or static-file denial behavior. Merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 28 functions across 24 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely identifies the primary change: adding the allowedOrigins option.
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

Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 28 functions across 24 files. (4 skipped: 4 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a770a2e0-d86a-4f33-90f4-0fa076fe7c75
📥 Commits

Reviewing files that changed from the base of the PR and between 9915359 and 390f797.

📒 Files selected for processing: 27
  • .changeset/independent-origin-authorization.md
  • README.md
  • examples/allowed-origins/README.md
  • examples/allowed-origins/app.js
  • examples/allowed-origins/webpack.config.js
  • lib/Server.js
  • lib/options.check.js
  • lib/options.json
  • test/__snapshots__/normalize-options.test.js.snap.webpack5
  • test/__snapshots__/validate-options.test.js.snap.webpack5
  • test/cli/__snapshots__/basic.test.js.snap.webpack5
  • test/cli/allowedOrigins-option.test.js
  • test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5
  • test/e2e/allowed-hosts.test.js
  • test/e2e/allowed-origins.test.js
  • test/e2e/cross-origin-request.test.js
  • test/e2e/event-source.test.js
  • test/e2e/options-middleware.test.js
  • test/e2e/proxy-web-socket-origin.test.js
  • test/e2e/web-socket-server-url.test.js
  • test/normalize-options.test.js
  • test/ports-map.js
  • test/schema-check.test.js
  • test/server/allowed-origins.test.js
  • test/server/proxy-option.test.js
  • test/validate-options.test.js
  • types/lib/Server.d.ts

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

Comment thread lib/Server.js Outdated
Comment thread lib/Server.js Outdated
@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.63%. Comparing base (b4eb797) to head (3d3355d).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5770      +/-   ##
==========================================
+ Coverage   95.15%   95.63%   +0.48%     
==========================================
  Files           6        6              
  Lines        5016     5526     +510     
==========================================
+ Hits         4773     5285     +512     
+ Misses        243      241       -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.

alexander-akait and others added 5 commits October 18, 2026 12:51
…t the hot token

`allowedOrigins: "auto"` (the default) now keeps the origin rules derived
from `allowedHosts` exactly, so nothing changes until the option is set;
`allowedHosts: "all"` and an `Access-Control-Allow-Origin: *` header still
open every origin under it, with a deprecation warning. A list allows the
page's own hostname plus the listed origins, answers them with CORS
headers and allows a plain script they load by its `Referer`; "all" allows
every origin and keeps the `Host` check. One rule now serves ordinary
requests, proxied WebSocket upgrades, hot clients and the internal
endpoints.

The injected hot client is handed a per-run token the endpoint does not
require (webpack-dev-middleware#2486), and a client carrying it may connect
from an origin the server does not know; skipped with an older middleware.

`static.deny` refuses secrets (`.env*`, keys and certificates, `.npmrc`,
`.yarnrc.yml`, `.git`) or patterns of your own in a static directory, and
hides them from listings; off by default until the next major.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 35fd4aa8-3b41-48b8-9409-38c2ebfee855
📥 Commits

Reviewing files that changed from the base of the PR and between c6467d1 and a13c785.

📒 Files selected for processing: 20
  • .changeset/independent-origin-authorization.md
  • .cspell.json
  • README.md
  • examples/allowed-origins/README.md
  • examples/allowed-origins/webpack.config.js
  • lib/Server.js
  • lib/hotOptions.js
  • lib/options.check.js
  • lib/options.json
  • test/__snapshots__/normalize-options.test.js.snap.webpack5
  • test/__snapshots__/validate-options.test.js.snap.webpack5
  • test/cli/__snapshots__/basic.test.js.snap.webpack5
  • test/e2e/allowed-origins.test.js
  • test/e2e/static-deny.test.js
  • test/hot-options.test.js
  • test/ports-map.js
  • test/server/allowed-origins-deprecation.test.js
  • test/server/allowed-origins.test.js
  • test/validate-options.test.js
  • types/lib/Server.d.ts
🚧 Files skipped from review as they are similar to previous changes: 2
  • .changeset/independent-origin-authorization.md
  • test/cli/snapshots/basic.test.js.snap.webpack5

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

Comment thread examples/allowed-origins/README.md Outdated
Comment thread README.md Outdated
alexander-akait and others added 2 commits October 18, 2026 13:39
With allowedOrigins set, a listed origin gets Access-Control-Allow-Credentials,
and an allowed origin's preflight gets the method, headers and Private
Network Access it asks for, so a fetch with custom headers, another method
or cookies works from it. "auto" is unchanged.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 39a7947f-74d3-4927-a3f1-0bce7d63078a
📥 Commits

Reviewing files that changed from the base of the PR and between cfaa21c and 0396299.

📒 Files selected for processing: 4
  • README.md
  • examples/allowed-origins/README.md
  • lib/Server.js
  • test/e2e/allowed-origins.test.js
🚧 Files skipped from review as they are similar to previous changes: 1
  • examples/allowed-origins/README.md

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

Comment thread lib/Server.js Outdated
alexander-akait and others added 2 commits October 18, 2026 14:23
…a Host

The hot-token tests now give the middleware a token when it has none, so
this server's own check runs on any webpack-dev-middleware rather than
being skipped; the optional-token detection takes a schema and is tested
on its own. static.deny gets the `?` glob, an undecodable path and the
Windows rules. The allowedOrigins entry check the schema already makes is
gone, and the token is read off the query without a try that cannot fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjuMAuk9o6UazjHzcAQCTA
A list also allows the page's own hostname on any port, and cookies do not
tell ports apart, so Access-Control-Allow-Credentials went to any other
local page with it. It now goes only to an origin listed by name.

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

Copy link
Copy Markdown
Member

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

alexander-akait and others added 2 commits October 18, 2026 16:20
…th allowedOrigins

8.5.0 takes `hot.token: { required: false }` (webpack/webpack-dev-middleware#2486),
so the check for it, the tests' stand-in token and the README notes on older
versions go, as their TODOs said. The token is handed to the injected client
only once `allowedOrigins` is set: under "auto" the socket's url and who it
lets in stay exactly as before, with a TODO to always hand it over in the
next major release.

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

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedwebpack-dev-middleware@​8.4.0 ⏵ 8.5.099 +110010097 +5100

View full report

Copy link
Copy Markdown
Member

@coderabbitai review


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

2 participants