← WebKit — 2026-W39

b1a58c0a3e7f5e5401d157e71c33f6eef21511be  [Site Isolation] backForwardItemAtIndexForWebContent returns main frame state for any unrecognized frameID

severity medium class InfoDisclosure confidence 0.66 signal score 9.06 Source/WebKit/UIProcess patch-now
Primitive: missing frame-ownership check lets a web process read back/forward FrameState for a frame it does not host
Triage note: Resolves the FIXME 'This should verify that the web process requesting the item hosts the specified frame' by adding frameOnPage()/frameOnPage check in backForwardItemAtIndexForWebContent and backForwardAllItems before returning copyFrameStateWithChildren(). Without it, a compromised/subframe web process could request session/history FrameState (URLs, form/scroll state) for frames in other processes - cross-process info disclosure reachable from a renderer.
Structural signals: smartptr_member_added (+6.47), null_guard (+2.59)

Commit message

[Site Isolation] backForwardItemAtIndexForWebContent returns main frame state for any unrecognized frameID
https://bugs.webkit.org/show_bug.cgi?id=322135
rdar://172058204

Reviewed by Alex Christensen.

If the entry had no item for the requested frameID, backForwardItemAtIndexForWebContent()
replied with the entry's main frame state. A subframe missing from that entry, an unknown
frameID, or another page's frame all got this page's main frame FrameState.

Both it and backForwardAllItems() now reply with nothing unless the frameID names a frame of
this page. Only a main frame still falls back to the entry's main frame state, because entries
can lack the main frame's current ID after a session restore or a process swap.

The frame check is not a MESSAGE_CHECK. Under site isolation a subframe process names the main
frame, which it does not host, whenever BackForwardController is called without a frameID. The
frame can also be destroyed while a synchronous request naming it is in flight.

Both the C++ and Swift implementations are changed.

Tests: http/tests/site-isolation/history/back-forward-item-at-index-cross-process-frame-id.html
       ipc/back-forward-item-at-index-frame-id.html

* LayoutTests/http/tests/site-isolation/history/back-forward-item-at-index-cross-process-frame-id-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/history/back-forward-item-at-index-cross-process-frame-id.html: Added.
* LayoutTests/http/tests/site-isolation/history/resources/back-forward-item-at-index-frame-id-probe.html: Added.
* LayoutTests/ipc/back-forward-item-at-index-frame-id-expected.txt: Added.
* LayoutTests/ipc/back-forward-item-at-index-frame-id.html: Added.
* LayoutTests/ipc/resources/back-forward-item-at-index-subframe.html: Added.
* Source/WebKit/UIProcess/WebBackForwardList.cpp:
(WebKit::frameOnPage):
(WebKit::WebBackForwardList::backForwardAllItems):
(WebKit::WebBackForwardList::backForwardItemAtIndexForWebContent):
* Source/WebKit/UIProcess/WebBackForwardList.swift:
* Source/WebKit/UIProcess/WebBackForwardListSwiftUtilities.h:
(webFrameForFrameID):

Canonical link: https://commits.webkit.org/321961@main

Before / after

Loading diff…