CVE-2026-13024
Overview
Files Changed
content/browser/renderer_host/render_frame_host_impl.cccontent/public/browser/disallow_activation_reason.h
Patch
From 80366988eaf9e38a0bf32220fa757e66ff95e8e2 Mon Sep 17 00:00:00 2001
From: Rakina Zata Amni <rakina@chromium.org>
Date: Mon, 08 Jun 2026 02:14:45 -0700
Subject: [PATCH] Only kill renderer on DidCommit while BFCached if ACKed, evict otherwise
The previous approach of killing the renderer on all DidCommits might
be killing legitimate DidCommit calls that were sent from the renderer
from before the document is actually BFCached. This CL makes it so that
we kill only calls coming from the renderers that already ACKed the
BFCaching. For renderers that haven't we simply just evict the RFH from
BFCache. In both cases we return early and don't continue processing
the DidCommit.
Bug: 520443189, 517148260
Change-Id: I4e3f1518e0d86c506127ee19a709aa5a28bc347c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7901822
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: Fergal Daly <fergal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1643048}
---
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index d57c0a6..1c38e9c 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -17263,8 +17263,18 @@
// kInBackForwardCache state. Trigger a renderer kill if we receive an
// unexpected DidCommit message.
if (IsInBackForwardCache()) {
- bad_message::ReceivedBadMessage(
- GetProcess(), bad_message::RFH_DID_COMMIT_NAVIGATION_WHILE_BFCACHED);
+ if (render_view_host()->DidReceiveBackForwardCacheAck()) {
+ bad_message::ReceivedBadMessage(
+ GetProcess(), bad_message::RFH_DID_COMMIT_NAVIGATION_WHILE_BFCACHED);
+ } else {
+ // The renderer might not have realized that it's in BFCache when it sent
+ // the DidCommitNavigation call, since we haven't received the BFCache
+ // ACK. In this case, just evict from BFCache instead of killing the
+ // renderer.
+ IsInactiveAndDisallowActivation(
+ DisallowActivationReasonId::kDidCommitNavigation);
+ }
+ // Return early in any case.
return;
}
diff --git a/content/public/browser/disallow_activation_reason.h b/content/public/browser/disallow_activation_reason.h
index 1ff1f7ed..f0c9fed 100644
--- a/content/public/browser/disallow_activation_reason.h
+++ b/content/public/browser/disallow_activation_reason.h
@@ -65,6 +65,7 @@
kIndexedDBTransactionIsOngoingAndBlockingOthers = 41,
kBrowserInitiatedErrorPage = 42,
kDidChangeOpener = 43,
+ kDidCommitNavigation = 44,
// New entries go above here. New entries should be added to
// tools/metrics/histograms/enums.xml .
kMinEmbedderDisallowActivationReason = 2 << 16,
Original Bug Report
Site Isolation Bypass via DidCommitProvisionalLoad on BFCached Subframes
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: A logical vulnerability in Back-Forward Cache (BFCache) navigation commit handling potentially allows a compromised renderer to bypass Site Isolation boundaries. By sending a synthetic synchronous commit IPC to a cached subframe, the renderer can manipulate the session history state of a cross-origin page in the foreground. This can result in spoofing the frame’s origin or injecting attacker-controlled content.
Affected files:
content/browser/renderer_host/render_frame_host_impl.cccontent/browser/renderer_host/navigation_entry_impl.cccontent/browser/renderer_host/navigation_controller_impl.cccontent/browser/renderer_host/frame_navigation_entry.cc
Estimated timestamp from git blame: 2020-06-10
Description
A potential logic vulnerability exists in Chromium’s navigation and Back-Forward Cache (BFCache) state handling. Under specific conditions, a compromised renderer process can exploit this flaw to overwrite or inject cross-origin session history state (FrameNavigationEntry) belonging to a foreground page, potentially leading to a Site Isolation bypass.
Root Cause Analysis
-
Message Filtering in Release Builds: The
mojom::FrameHost::DidCommitProvisionalLoadIPC is dispatched toRenderFrameHostImpl::DidCommitNavigation. The browser-sideBackForwardCacheMessageFilter::WillDispatchdoes not discard these messages in release builds under default logging/dumping policies. InsideRenderFrameHostImpl::DidCommitNavigation(incontent/browser/renderer_host/render_frame_host_impl.cc), the assertion preventing navigation commits while in the back-forward cache is debug-only:DCHECK(!IsInBackForwardCache());In production release builds, this assertion is compiled out, allowing the commit to proceed.
-
Subframe Owner Retention: When a page enters the BFCache, the top-level main frame’s
owner_is cleared. However, nested subframeRenderFrameHostImplobjects retain theirowner_pointers (referencing their parentFrameTreeNode), meaning validation checks such asCHECK(owner_)continue to pass. -
Synchronous Commit Route: If the subframe was left unnavigated prior to entering the BFCache,
is_on_initial_empty_document_istrue. By sending a commit toabout:blank, the renderer satisfies the conditions forIsInitialSynchronousAboutBlankCommitand routes the execution along the synchronous commit path, generating a syntheticNavigationRequestin the browser. -
Targeting Active Controller: Since the cached subframe remains associated with the active tab’s
FrameTree, callingNavigator::DidNavigateroutes the commit to the activeNavigationControllerImplof the foreground tab (which represents the victim’s cross-origin page). -
FrameNavigationEntry Confusion: In
NavigationEntryImpl::AddOrUpdateFrameEntry, the parent node of the BFCached subframe is resolved viaGetTreeNode(FrameTreeNode::From(frame_tree_node->parent())). Because the parent is a main frame,MatchesFrameincorrectly matches it against the root node of the active foreground page’sNavigationEntry. The browser then matches the subframe’s unique name against the active page’s subframes, allowing the attacker to overwrite the victim’sFrameNavigationEntryfields (e.g.,committed_origin_,site_instance_,page_state_) or append a new entry.
Suggested / Potential Attack Steps (Conceptual)
Note: These steps are based on static code analysis; our tooling does not currently run executable proof-of-concept code.
- A compromised renderer process representing an attacker-controlled origin (e.g.,
https://evil.com) creates a subframe viaCreateChildFramewith a unique name matching a target subframe of a victim site (e.g.,https://victim.com). - The attacker leaves this subframe on its initial empty document.
- The main frame navigates to
https://victim.com, causing theevil.compage to enter the BFCache. - The compromised renderer sends a
DidCommitProvisionalLoadIPC to the cached subframe forabout:blankwithPAGE_TRANSITION_AUTO_SUBFRAMEand attacker-specified sequence numbers/page state. - The active
victim.compage’s subframe history entry is modified or appended with the attacker’s site instance and page state.
Recommended Remediation
Convert the debug-only assertion in RenderFrameHostImpl::DidCommitNavigation into a security-critical check to safely discard unexpected commits from cached frames in release builds:
if (IsInBackForwardCache()) {
bad_message::ReceivedBadMessage(GetProcess(), bad_message::RFH_COMMIT_WHILE_CACHED);
return;
}
Additionally, ensure that BackForwardCacheMessageFilter strictly rejects or triggers eviction upon receiving any unexpected navigation-related IPCs while the document is cached.
Evaluated with Chrome root at commit: b1520ef4a76878853a31f0943b565e42060edec8
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.