Skip to content

fix: enforce blockHosts on the browser network path in Chrome - #34788

Open
AtofStryker wants to merge 1 commit into
developfrom
bill/34785-blockhosts-browser-network-path
Open

fix: enforce blockHosts on the browser network path in Chrome#34788
AtofStryker wants to merge 1 commit into
developfrom
bill/34785-blockhosts-browser-network-path

Conversation

@AtofStryker

@AtofStryker AtofStryker commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Additional details

blockHosts was silently ignored on the browser network (CDP Fetch) path in Chrome, Chromium, and Edge. The blocked-hosts policy matched and wrote a 503, but the pipeline then threw it away.

The synthetic response used on that path is a Node Writable. A Writable auto-destroys after end(), so a response a middleware finished itself read as destroyed. createLegacyProxyPipeline treats a destroyed response as a browser cancel and throws. The CDP transport catches that and releases the paused request untouched, so the blocked script loaded from the real origin. A real http.ServerResponse never sets destroyed on end(), which is why the MITM path was unaffected. The unload redirect (RedirectToClientRouteIfUnloaded) hit the same bug.

The fix narrows the cancel check to "destroyed before finished". forceNetworkError still works, since net-stubbing destroys the response without finishing it.

Why CI missed it: block_hosts_spec.js and block_hosts_override_spec.js passed no browser option, so systemTests.exec skipped them whenever BROWSER was set. The system-tests-chrome job reported them as pending and they only ever ran on Electron. Both specs now run on Chrome and Electron. Against the old check, the Chrome run fails with expected 200 to equal 0.

Steps to test

  1. Check out the reporter's repro: https://github.com/verheyenkoen/cypress16-http2-blockhosts-bug
  2. Run it with this branch in Chrome. The page should read blockHosts works! and the spec should pass.
  3. yarn workspace @packages/proxy test -- test/unit/http/index.spec.ts — the new test fails if the writableFinished guard is removed.
  4. yarn workspace @tooling/system-tests test block_hosts — runs both specs on Chrome and Electron.

How has the user experience changed?

Requests to a blockHosts host fail with a 503 again in Chrome, Chromium, and Edge. No visual change.

PR Tasks

  • Is there an associated issue with maintainer approval for PR submission?
  • Have tests been added/updated?
  • [na] Has a PR for user-facing changes been opened in cypress-documentation?
  • [na] Have API changes been updated in the type definitions?

Note

Medium Risk
Touches core HTTP interception/cancel logic on the CDP Fetch path; incorrect handling could still leak blocked requests or break cancel/forceNetworkError behavior, but scope is a narrow guard with targeted tests.

Overview
Fixes a 16.0.0 regression where blockHosts did not block traffic in Chrome, Chromium, and Edge: blocked requests could still hit the network and load scripts/resources instead of failing with 503.

On the native browser network (CDP Fetch) path, request middleware ends the client response on a synthetic Writable that auto-destroys after end(). createLegacyProxyPipeline treated any destroyed response as a browser cancel, threw, and the CDP layer released the paused request to the origin—discarding the blocked-host 503 (same class of bug as unload redirects). The change only skips response middleware when the response is destroyed and not writableFinished, so finished synthetic responses (blocked host, redirect) complete normally; forceNetworkError behavior is unchanged.

Adds a unit test for middleware that ends with 503, updates blockHosts system tests to run on Chrome and Electron (they previously skipped Chrome when BROWSER was set), and documents the fix in the changelog.

Reviewed by Cursor Bugbot for commit 034c010. Bugbot is set up for automated code reviews on this repo. Configure here.

The synthetic response used on the CDP Fetch path auto-destroys after
end(), so a 503 written by the blocked-hosts policy read as a browser
cancel. The pipeline threw and the transport released the paused request
untouched, so blocked hosts loaded from the real origin. Only treat a
response destroyed before it finished as a cancel.

Run the blockHosts system specs on Chrome as well as Electron; they were
skipped in the system-tests-chrome job.

Closes #34785

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@AtofStryker AtofStryker self-assigned this Sep 4, 2026
@AtofStryker
AtofStryker requested review from a team, cacieprins and mschile September 4, 2026 17:17
@AtofStryker AtofStryker changed the title fix: enforce blockHosts on the browser network path in Chrome fix: enforce blockHosts on the browser network path in Chrome Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

blockHosts doesn't work with HTTP/2 in Cypress 16

1 participant