CVE-2025-24208
Overview
Background
- createNewPage / window.open
- The UI-process flow that creates a new page when content calls window.open, delegating to the app’s UI client.
- javascript: URL
- A URL scheme whose body executes as script in the loading document’s context; loading it in the wrong context is XSS.
- Single-window app
- A UI client that handles window.open by loading into the existing view, which is where the javascript: URL slipped in.
Root Cause Analysis
This fixes a cross-site-scripting vector where a javascript: URL could be loaded during the window.open (createNewPage) flow. When web content calls window.open, WebPageProxy::createNewPage asks the app’s UI client to create a new page; in a single-window app the client may respond by loading the requested URL into the existing view via WebPageProxy::loadRequest. A cross-origin subframe calling window.open(‘javascript:…’) could thereby get a javascript: URL loaded through this path and executed in the opener/host page’s context — a universal/cross-site scripting condition, because the javascript: URL runs with the wrong document’s origin rather than being blocked.
The fix adds an m_isCallingCreateNewPage flag: it is set true immediately before invoking the UI client’s createNewPage and cleared in the createNewPage completion handler, and WebPageProxy::loadRequest now returns nullptr (refusing the load) when m_isCallingCreateNewPage is true and request.url().protocolIsJavaScript().
The restored invariant is that javascript: URLs cannot be loaded through the createNewPage window. The regression test loads a javascript: URL via window.open from a cross-origin iframe and expects the loadRequest to be refused (NULL).
Attack Path
- Embed a cross-origin iframe A page loads a cross-origin subframe.
- Call window.open('javascript:...') The subframe calls window.open with a javascript: URL.
- Load during createNewPage The single-window UI client responds by calling loadRequest with the javascript: URL during createNewPage.
- Cross-site script execution The javascript: URL executes in the host/opener page’s context, a cross-site scripting attack.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
WebPageProxy::loadRequestSource/WebKit/UIProcess/WebPageProxy.cpp |
modified | Returns nullptr for a javascript: URL while m_isCallingCreateNewPage is true, blocking the load during the window.open flow. |
WebPageProxy::createNewPageSource/WebKit/UIProcess/WebPageProxy.cpp |
modified | Sets m_isCallingCreateNewPage around the UI client's createNewPage call and clears it in the completion handler. |
WebPageProxy::m_isCallingCreateNewPageSource/WebKit/UIProcess/WebPageProxy.h |
modified | New flag marking the window that a javascript: URL must not be loaded through. |
Files Changed
Source/WebKit/UIProcess/WebPageProxy.cppSource/WebKit/UIProcess/WebPageProxy.hTools/TestWebKitAPI/Tests/WebKitCocoa/OpenAndCloseWindow.mm
Audit Directions
- javascript: URL entry pointsGrep WebPageProxy for loadRequest/loadData paths that can receive a protocolIsJavaScript() URL from content without an origin/context gate.
- createNewPage side effectsAudit the createNewPage / UI-client flow for other requests that can be loaded into the host page during window.open.