Medium CVSS 7.5 webkit Bypass 🔧 Commit mapped

Overview

Medium
Severity
7.5
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may disclose sensitive user information
ComponentWTF
Bug ClassBypass
Tracker292888
Fix commitc3811ccef959 (WebKit/WebKit) +265/-65
CWECWE-359
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CISA KEVNot listed
CreditedGilad Moav, Yehuda Afek, Anat Bremler-Barr, and Amit Klein
Disclosed2025-07-29

Background

portAllowed
The WTF/URL routine that returns whether a URL’s port may be connected to, consulted before WebKit issues network requests.
Port blocking / blockedPortList
A denylist of TCP ports (e.g. FTP, SMTP, NetBIOS) that browsers refuse to connect to over web protocols to prevent protocol-confusion and abuse.
Fetch spec port blocking
The WHATWG-standardized list of bad ports (https://fetch.spec.whatwg.org/#port-blocking) that user agents must block; WebKit now aligns to it plus port 0.
Port 0
A reserved TCP port not valid for real connections and used by some systems as a wildcard/ephemeral selector, whose acceptance can enable probing or inconsistent behavior across platforms.
Timing side channel
Inferring otherwise-hidden information (like host/service reachability) from measurable differences in how long operations take or which callbacks fire.

Root Cause Analysis

This is a logic error (a missing entry in a security denylist) in wtf::portAllowed in Source/WTF/wtf/URL.cpp, the function WebKit uses to decide whether a URL’s port is permitted for outbound connections. The function early-returns true when the port is falsy (if (!port) return true;) and otherwise checks the port against a static blockedPortList. Before the patch that list was derived from Mozilla’s historical port-banning list and did not contain port 0; combined with the !port early return, port 0 was treated as ’no port specified’ / allowed rather than as an explicit, attacker-supplied restricted port. The invariant that should hold is that reserved/dangerous ports — including port 0, which is not a valid connectable TCP port and is used by some stacks as a wildcard/ephemeral selector — must be blocked so web content cannot direct the browser to attempt connections to them.

The fix rewrites the list to follow the WHATWG Fetch spec’s port-blocking list ‘with the addition of port 0’, adding 0, // reserved as the first entry (and updating the guiding comment/URL from the Mozilla reference to https://fetch.spec.whatwg.org/#port-blocking). The added layout tests confirm the new behavior: a fetch to https://does-not-exist.com:0/ now yields the console message ‘Not allowed to use restricted network port 0’, and the platform block-test expectations now include port 0 among the blocked ports. Note the !port early return is unchanged in the shown diff; whether an explicit ‘:0’ reaches portAllowed as port==0 (and is now caught by the list) versus being normalized earlier is only partially visible, but the added test proving port 0 is blocked and the CVE’s information-disclosure framing indicate the observable gap was that connections/attempts to port 0 were previously permitted.

Key insight
The vulnerability was an incomplete security denylist: port 0 was absent from WebKit’s blocked-port list, so a reserved, non-connectable port slipped past the port policy and became a side-channel/probing vector — fixed by adopting the Fetch spec list and explicitly blocking port 0.

Attack Path

  1. Serve malicious web content The attacker gets a victim to load a page under attacker control (or injects script into a context that can issue fetches/resource loads).
  2. Issue a request to port 0 From the page, initiate a subresource load or fetch("https://host:0/") targeting an internal or arbitrary host on port 0, which pre-patch was not in the blocked port list and thus not rejected by portAllowed.
  3. Measure timing/behavioral side channels As the test’s own comment (‘attempts to measure performance based on the zero port’) hints, observe timing or error-callback differences between allowed vs. blocked/failed connections to infer information such as host reachability or network state.
  4. Disclose sensitive information Aggregate the observed differences to disclose sensitive user/network information (e.g. probe internal services), the impact the CVE describes; post-patch the request is rejected with ‘Not allowed to use restricted network port 0’ before any such attempt.

Impact Assessment

This is a policy/denylist logic error, not a memory-safety bug: there is no OOB/UAF primitive and no path to code execution from the diff. The realistic impact, matching the CVE, is information disclosure — web content could direct connection attempts to port 0 and use timing/behavioral differences to probe network or host state that should be off-limits. The connection policy is enforced in the process that performs URL loading (WebContent/Network path); the fix simply denies port 0, closing the probing avenue rather than mitigating corruption.

Changed Functions

FunctionChangeNotes
portAllowed
Source/WTF/wtf/URL.cpp
modified Replaces the Mozilla-derived blockedPortList with the WHATWG Fetch-spec port-blocking list and adds `0 // reserved` as a blocked port; updates the reference comment/URL. Net effect: URLs with port 0 are now rejected instead of allowed.

Files Changed

  • LayoutTests/http/tests/security/block-connection-to-zero-port.https-expected.txt
  • LayoutTests/http/tests/security/block-connection-to-zero-port.https.html
  • LayoutTests/platform/gtk-wk2/security/block-test-expected.txt
  • LayoutTests/platform/wpe/security/block-test-expected.txt
  • Source/WTF/wtf/URL.cpp

Audit Directions

  • Completeness of blockedPortList vs. Fetch spec
    Diff WebKit’s blockedPortList against the current WHATWG Fetch port-blocking list for any other missing or stale entries; grep URL.cpp for blockedPortList and confirm ordering/binary-search assumptions still hold after inserting 0.
  • The `!port` early-return and port normalization
    Trace how ‘:0’ and empty ports are parsed and normalized before portAllowed (grep for port(), parsePort, defaultPortForProtocol, !port) to ensure port 0 is not still short-circuited to ‘allowed’ on some path or protocol.
  • Other connection-policy denylists
    Look for parallel allow/deny checks (mixed-content, local-network/private-network access, scheme allowlists) that gate outbound requests; grep for ‘restricted network port’, ‘Not allowed to use’, and per-scheme port defaults to find lists that may similarly omit reserved values.

Original Bug Report

The reporter's bug is still restricted on the tracker.