CVE-2025-43227
Overview
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.
Attack Path
- 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).
- 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. - 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.
- 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
Changed Functions
| Function | Change | Notes |
|---|---|---|
portAllowedSource/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.txtLayoutTests/http/tests/security/block-connection-to-zero-port.https.htmlLayoutTests/platform/gtk-wk2/security/block-test-expected.txtLayoutTests/platform/wpe/security/block-test-expected.txtSource/WTF/wtf/URL.cpp
Audit Directions
- Completeness of blockedPortList vs. Fetch specDiff WebKit’s blockedPortList against the current WHATWG Fetch port-blocking list for any other missing or stale entries; grep URL.cpp for
blockedPortListand confirm ordering/binary-search assumptions still hold after inserting 0. - The `!port` early-return and port normalizationTrace 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 denylistsLook 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.