Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient data validation in PDF
DescriptionInsufficient data validation in PDF
ComponentPDF
Bug ClassLogic Error
Tracker513721370
Fix commit52d248ec1b45 (chromium/src) +105/-11
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
ChromeContentBrowserClientMimeHandlerFilePickerTest
chrome/browser/chrome_content_browser_client_unittest.cc
modified
TEST_F
extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
modified

Files Changed

  • chrome/browser/chrome_content_browser_client_unittest.cc
  • extensions/browser/mime_handler/mime_handler_stream_manager.cc
  • extensions/browser/mime_handler/mime_handler_stream_manager.h
  • extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
From 52d248ec1b458742821438e2b412042117bf7a18 Mon Sep 17 00:00:00 2001
From: Andy Phan <andyphan@chromium.org>
Date: Fri, 29 May 2026 16:46:28 -0700
Subject: [PATCH] [mime_handler] Verify embedder URL in MimeHandlerStreamManager

Verify that the embedder frame's last committed URL matches the original
PDF URL in IsExtensionFrameTreeNodeId() and IsContentFrameTreeNodeId().

Previously, these privilege-granting predicates only verified the
FrameTreeNodeId, leaving them vulnerable to same-document URL spoofing
(e.g., via history.pushState) which allowed cross-origin pages to
inherit PDF extension privileges.

This CL updates the predicates to compare the URLs while ignoring
fragment/hash differences using GetWithoutRef(), preventing spoofing
while ensuring legitimate hash changes (e.g., scrolling) do not break
the viewer.

Also update ChromeContentBrowserClientMimeHandlerFilePickerTest unit
tests to commit the matching original stream URL, satisfying the new
browser-process URL verification checks.

Bug: 513248926, 513721370
Change-Id: I47ceaefddc208f16aa226f401b30d6036aac77fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7884085
Commit-Queue: Andy Phan <andyphan@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1638817}
---

diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index 8650874..bfe1d23 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -2283,9 +2283,6 @@
 #endif  // BUILDFLAG(ENABLE_PDF)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS) && !BUILDFLAG(IS_ANDROID)
-constexpr char kMimeHandlerViewerUrl[] =
-    "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/viewer.html";
-
 class ChromeContentBrowserClientMimeHandlerFilePickerTest
     : public ChromeRenderViewHostTestHarness {
  public:
@@ -2293,6 +2290,10 @@
   ~ChromeContentBrowserClientMimeHandlerFilePickerTest() override = default;
 
  protected:
+  static constexpr char kMimeHandlerViewerUrl[] =
+      "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/viewer.html";
+  static constexpr char kOriginalUrl[] = "https://original_url1";
+
   content::RenderFrameHost* CreateChild(content::RenderFrameHost* parent,
                                         const std::string& name) {
     auto* parent_tester = content::RenderFrameHostTester::For(parent);
@@ -2333,7 +2334,7 @@
 // file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        FullPageMimeHandlerExtensionFrameAllowed) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
 
@@ -2351,7 +2352,7 @@
   content::RenderFrameHost* embedder_host =
       CreateChild(main_rfh(), "embedded-mime-handler");
   embedder_host = content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("https://embedder.test/file.foo"), embedder_host);
+      GURL(kOriginalUrl), embedder_host);
   content::RenderFrameHost* extension_host = CreateMimeHandlerExtensionHost(
       embedder_host, GURL(kMimeHandlerViewerUrl));
 
@@ -2366,7 +2367,7 @@
 // extension origin, is allowed to show a file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        DescendantOfMimeHandlerExtensionFrameAllowed) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
   content::RenderFrameHost* descendant =
@@ -2400,7 +2401,7 @@
 // extension host's committed origin is denied a file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        MimeHandlerExtensionFrameWithMismatchedOriginDenied) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
 
diff --git a/extensions/browser/mime_handler/mime_handler_stream_manager.cc b/extensions/browser/mime_handler/mime_handler_stream_manager.cc
index 3dc09aa..fab27a2f 100644
--- a/extensions/browser/mime_handler/mime_handler_stream_manager.cc
+++ b/extensions/browser/mime_handler/mime_handler_stream_manager.cc
@@ -266,7 +266,10 @@
     content::FrameTreeNodeId frame_tree_node_id) const {
   const auto* stream_info = GetClaimedStreamInfo(embedder_host);
   return stream_info &&
-         frame_tree_node_id == stream_info->extension_host_frame_tree_node_id();
+         frame_tree_node_id ==
+             stream_info->extension_host_frame_tree_node_id() &&
+         embedder_host->GetLastCommittedURL().EqualsIgnoringRef(
+             stream_info->stream()->original_url());
 }
 
 bool MimeHandlerStreamManager::DidExtensionFrameFinishNavigation(
@@ -300,7 +303,9 @@
     content::FrameTreeNodeId frame_tree_node_id) const {
   const auto* stream_info = GetClaimedStreamInfo(embedder_host);
   return stream_info &&
-         frame_tree_node_id == stream_info->content_host_frame_tree_node_id();
+         frame_tree_node_id == stream_info->content_host_frame_tree_node_id() &&
+         embedder_host->GetLastCommittedURL().EqualsIgnoringRef(
+             stream_info->stream()->original_url());
 }
 
 bool MimeHandlerStreamManager::DidContentFrameFinishNavigation(
diff --git a/extensions/browser/mime_handler/mime_handler_stream_manager.h b/extensions/browser/mime_handler/mime_handler_stream_manager.h
index 1f4a5abf..11a8d33 100644
--- a/extensions/browser/mime_handler/mime_handler_stream_manager.h
+++ b/extensions/browser/mime_handler/mime_handler_stream_manager.h
@@ -141,7 +141,8 @@
   bool IsExtensionHost(const content::RenderFrameHost* render_frame_host) const;
 
   // Returns true if `frame_tree_node_id` is the frame tree node ID for the
-  // extension frame under `embedder_host`, false otherwise.
+  // extension frame under `embedder_host` and the `embedder_host`'s last
+  // committed URL matches the stream's original URL, false otherwise.
   bool IsExtensionFrameTreeNodeId(
       const content::RenderFrameHost* embedder_host,
       content::FrameTreeNodeId frame_tree_node_id) const;
@@ -160,7 +161,8 @@
   bool IsContentHost(const content::RenderFrameHost* render_frame_host) const;
 
   // Returns true if `frame_tree_node_id` is the frame tree node ID for the
-  // content frame under `embedder_host`, false otherwise.
+  // content frame under `embedder_host` and the `embedder_host`'s last
+  // committed URL matches the stream's original URL, false otherwise.
   bool IsContentFrameTreeNodeId(
       const content::RenderFrameHost* embedder_host,
       content::FrameTreeNodeId frame_tree_node_id) const;
diff --git a/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc b/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
index e1dc62e..7abefee 100644
--- a/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
+++ b/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
@@ -1264,4 +1264,90 @@
   EXPECT_FALSE(manager->GetTopLevelHandlerExtensionId().has_value());
 }
 
+// MimeHandlerStreamManager host privilege status should be correctly revoked
+// during a pushState URL path spoofing same-document navigation.
+TEST_F(MimeHandlerStreamManagerTest, HostPrivilegeBypassWithPushState) {
+  const GURL pdf_url(kOriginalUrl1);
+
+  content::RenderFrameHost* embedder_host =
+      NavigateAndCommit(main_rfh(), pdf_url);
+  auto* extension_host =
+      CreateChildRenderFrameHost(embedder_host, "extension host");
+  auto* content_host =
+      CreateChildRenderFrameHost(extension_host, "content host");
+  content_host = NavigateAndCommit(content_host, pdf_url);
+
+  MimeHandlerStreamManager* manager = mime_handler_stream_manager();
+  manager->AddStreamContainer(
+      embedder_host->GetFrameTreeNodeId(), "internal_id",
+      extensions::mime_handler::GenerateSampleStreamContainer(1),
+      std::make_unique<NiceMock<MockMimeHandlerStreamDelegate>>());
+  manager->ClaimStreamInfoForTesting(embedder_host);
+  manager->SetExtensionFrameTreeNodeIdForTesting(
+      embedder_host, extension_host->GetFrameTreeNodeId());
+  manager->SetContentFrameTreeNodeIdForTesting(
+      embedder_host, content_host->GetFrameTreeNodeId());
+
+  content::OverrideLastCommittedOrigin(
+      extension_host,
+      url::Origin::Create(GURL(
+          "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html")));
+
+  // Initially, both extension and content frames should have host privileges.
+  EXPECT_TRUE(manager->IsExtensionHost(extension_host));
+  EXPECT_TRUE(manager->IsContentHost(content_host));
+
+  // Simulate pushState URL spoofing on the embedder host.
+  auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+      GURL("https://original_url1/spoofed"), embedder_host);
+  simulator->CommitSameDocument();
+
+  // Spoofed URL path must revoke the privileges.
+  EXPECT_FALSE(manager->IsExtensionHost(extension_host));
+  EXPECT_FALSE(manager->IsContentHost(content_host));
+}
+
+// MimeHandlerStreamManager should continue to identify the extension and
+// content frames during same-document fragment/hash navigations on the
+// embedder host (e.g., scrolling).
+TEST_F(MimeHandlerStreamManagerTest, AllowsFragmentNavigation) {
+  const GURL pdf_url(kOriginalUrl1);
+
+  content::RenderFrameHost* embedder_host =
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc
index 8650874..bfe1d23 100644
--- a/chrome/browser/chrome_content_browser_client_unittest.cc
+++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -2283,9 +2283,6 @@
 #endif  // BUILDFLAG(ENABLE_PDF)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS) && !BUILDFLAG(IS_ANDROID)
-constexpr char kMimeHandlerViewerUrl[] =
-    "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/viewer.html";
-
 class ChromeContentBrowserClientMimeHandlerFilePickerTest
     : public ChromeRenderViewHostTestHarness {
  public:
@@ -2293,6 +2290,10 @@
   ~ChromeContentBrowserClientMimeHandlerFilePickerTest() override = default;
 
  protected:
+  static constexpr char kMimeHandlerViewerUrl[] =
+      "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/viewer.html";
+  static constexpr char kOriginalUrl[] = "https://original_url1";
+
   content::RenderFrameHost* CreateChild(content::RenderFrameHost* parent,
                                         const std::string& name) {
     auto* parent_tester = content::RenderFrameHostTester::For(parent);
@@ -2333,7 +2334,7 @@
 // file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        FullPageMimeHandlerExtensionFrameAllowed) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
 
@@ -2351,7 +2352,7 @@
   content::RenderFrameHost* embedder_host =
       CreateChild(main_rfh(), "embedded-mime-handler");
   embedder_host = content::NavigationSimulator::NavigateAndCommitFromDocument(
-      GURL("https://embedder.test/file.foo"), embedder_host);
+      GURL(kOriginalUrl), embedder_host);
   content::RenderFrameHost* extension_host = CreateMimeHandlerExtensionHost(
       embedder_host, GURL(kMimeHandlerViewerUrl));
 
@@ -2366,7 +2367,7 @@
 // extension origin, is allowed to show a file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        DescendantOfMimeHandlerExtensionFrameAllowed) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
   content::RenderFrameHost* descendant =
@@ -2400,7 +2401,7 @@
 // extension host's committed origin is denied a file picker.
 TEST_F(ChromeContentBrowserClientMimeHandlerFilePickerTest,
        MimeHandlerExtensionFrameWithMismatchedOriginDenied) {
-  NavigateAndCommit(GURL("https://example.test/document"));
+  NavigateAndCommit(GURL(kOriginalUrl));
   content::RenderFrameHost* extension_host =
       CreateMimeHandlerExtensionHost(main_rfh(), GURL(kMimeHandlerViewerUrl));
diff --git a/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc b/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
index e1dc62e..7abefee 100644
--- a/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
+++ b/extensions/browser/mime_handler/mime_handler_stream_manager_unittest.cc
@@ -1264,4 +1264,90 @@
   EXPECT_FALSE(manager->GetTopLevelHandlerExtensionId().has_value());
 }
 
+// MimeHandlerStreamManager host privilege status should be correctly revoked
+// during a pushState URL path spoofing same-document navigation.
+TEST_F(MimeHandlerStreamManagerTest, HostPrivilegeBypassWithPushState) {
+  const GURL pdf_url(kOriginalUrl1);
+
+  content::RenderFrameHost* embedder_host =
+      NavigateAndCommit(main_rfh(), pdf_url);
+  auto* extension_host =
+      CreateChildRenderFrameHost(embedder_host, "extension host");
+  auto* content_host =
+      CreateChildRenderFrameHost(extension_host, "content host");
+  content_host = NavigateAndCommit(content_host, pdf_url);
+
+  MimeHandlerStreamManager* manager = mime_handler_stream_manager();
+  manager->AddStreamContainer(
+      embedder_host->GetFrameTreeNodeId(), "internal_id",
+      extensions::mime_handler::GenerateSampleStreamContainer(1),
+      std::make_unique<NiceMock<MockMimeHandlerStreamDelegate>>());
+  manager->ClaimStreamInfoForTesting(embedder_host);
+  manager->SetExtensionFrameTreeNodeIdForTesting(
+      embedder_host, extension_host->GetFrameTreeNodeId());
+  manager->SetContentFrameTreeNodeIdForTesting(
+      embedder_host, content_host->GetFrameTreeNodeId());
+
+  content::OverrideLastCommittedOrigin(
+      extension_host,
+      url::Origin::Create(GURL(
+          "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html")));
+
+  // Initially, both extension and content frames should have host privileges.
+  EXPECT_TRUE(manager->IsExtensionHost(extension_host));
+  EXPECT_TRUE(manager->IsContentHost(content_host));
+
+  // Simulate pushState URL spoofing on the embedder host.
+  auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+      GURL("https://original_url1/spoofed"), embedder_host);
+  simulator->CommitSameDocument();
+
+  // Spoofed URL path must revoke the privileges.
+  EXPECT_FALSE(manager->IsExtensionHost(extension_host));
+  EXPECT_FALSE(manager->IsContentHost(content_host));
+}
+
+// MimeHandlerStreamManager should continue to identify the extension and
+// content frames during same-document fragment/hash navigations on the
+// embedder host (e.g., scrolling).
+TEST_F(MimeHandlerStreamManagerTest, AllowsFragmentNavigation) {
+  const GURL pdf_url(kOriginalUrl1);
+
+  content::RenderFrameHost* embedder_host =
+      NavigateAndCommit(main_rfh(), pdf_url);
+  auto* extension_host =
+      CreateChildRenderFrameHost(embedder_host, "extension host");
+  auto* content_host =
+      CreateChildRenderFrameHost(extension_host, "content host");
+  content_host = NavigateAndCommit(content_host, pdf_url);
+
+  MimeHandlerStreamManager* manager = mime_handler_stream_manager();
+  manager->AddStreamContainer(
+      embedder_host->GetFrameTreeNodeId(), "internal_id",
+      extensions::mime_handler::GenerateSampleStreamContainer(1),
+      std::make_unique<NiceMock<MockMimeHandlerStreamDelegate>>());
+  manager->ClaimStreamInfoForTesting(embedder_host);
+  manager->SetExtensionFrameTreeNodeIdForTesting(
+      embedder_host, extension_host->GetFrameTreeNodeId());
+  manager->SetContentFrameTreeNodeIdForTesting(
+      embedder_host, content_host->GetFrameTreeNodeId());
+
+  content::OverrideLastCommittedOrigin(
+      extension_host,
+      url::Origin::Create(GURL(
+          "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html")));
+
+  EXPECT_TRUE(manager->IsExtensionHost(extension_host));
+  EXPECT_TRUE(manager->IsContentHost(content_host));
+
+  // Simulate a fragment/hash navigation on the embedder host (e.g. scrolling
+  // updates hash).
+  auto simulator = content::NavigationSimulator::CreateRendererInitiated(
+      GURL("https://original_url1#page=2"), embedder_host);
+  simulator->CommitSameDocument();
+
+  EXPECT_TRUE(manager->IsExtensionHost(extension_host));
+  EXPECT_TRUE(manager->IsContentHost(content_host));
+}
+
 }  // namespace extensions::mime_handler
Loading diff…

Original Bug Report

reported by vm...@google.com

Bypass of JavaScript content settings and cookie partitioning in OOPIF-PDF

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 logic desynchronization in how the browser identifies privileged PDF frames allows a compromised renderer to bypass JavaScript content settings and cookie partitioning. By using history.pushState to desynchronize an embedder’s URL, an attacker can bypass navigation throttles while retaining privileged status for a cross-origin victim site. This results in the victim site executing JavaScript despite blocks and accessing partitioned cookies.

Affected files:

  • chrome/browser/content_settings/page_specific_content_settings_delegate.cc
  • extensions/browser/mime_handler/mime_handler_stream_manager.cc
  • chrome/browser/pdf/chrome_pdf_stream_delegate.cc
  • components/pdf/browser/pdf_navigation_throttle.cc
  • chrome/browser/chrome_content_browser_client.cc
  • components/content_settings/browser/page_specific_content_settings.cc

Estimated timestamp from git blame: 2024-03-19

Summary

A potential vulnerability exists in the OOPIF-PDF (Out-of-Process Iframe PDF) viewer where the browser process’s predicates for identifying privileged frames fail to verify the embedder’s URL. An attacker with a compromised renderer can exploit this to bypass ‘Block JavaScript’ content settings and cookie partitioning protections (like CHIPS and SameSite=Lax/Strict) for arbitrary origins.

Root Cause Analysis

The OOPIF-PDF architecture uses a three-level frame hierarchy: Embedder Host (web page), Extension Host (chrome-extension://...), and Content Host (the plugin frame). The MimeHandlerStreamManager manages the metadata (StreamInfo) for these frames.

There is a discrepancy in how the browser validates these frames:

  1. Navigation Throttling: PdfNavigationThrottle (via ChromePdfStreamDelegate::ShouldAllowPdfFrameNavigation) calls MimeHandlerStreamManager::GetStreamContainer. This function correctly verifies that the embedder’s last committed URL matches the original PDF URL (extensions/browser/mime_handler/mime_handler_stream_manager.cc:223).
  2. Privilege Granting: Predicates like IsExtensionHost and IsContentHost (used by PageSpecificContentSettings and ChromeContentBrowserClient) rely on GetClaimedStreamInfo. This function performs a lookup using only the FrameTreeNodeId and GlobalRenderFrameHostId, omitting the URL validation check (extensions/browser/mime_handler/mime_handler_stream_manager.cc:665).

By using history.pushState in the embedder frame, an attacker can cause the URL check in GetStreamContainer to fail, leading the navigation throttle to permit a cross-origin navigation of the extension frame to a victim site. However, during the ReadyToCommit stage, the privilege-granting predicates still return true, granting the victim site the privileges intended for the PDF viewer.

Potential Exploitation Path

  1. A compromised renderer at https://attacker.com loads a PDF in an iframe. The browser registers a StreamInfo for the resulting extension frame.
  2. The attacker executes history.pushState({}, '', '/spoofed') in the top-level (embedder) frame. This updates the frame’s last committed URL without changing its ID.
  3. The attacker triggers a navigation of the child PDF extension frame to https://victim.com.
  4. PdfNavigationThrottle intercepts the navigation. Because the embedder’s URL (/spoofed) no longer matches the PDF’s original URL, GetStreamContainer returns nullptr. The throttle assumes the frame is no longer an active PDF viewer and permits the navigation.
  5. Upon commit of https://victim.com, the browser calls IsFrameAllowlistedForJavaScript. Because this check does not verify the embedder’s URL, it returns true based on the persistent FrameTreeNodeId mapping. This sets allow_script = true in the navigation parameters, bypassing any JavaScript block settings for victim.com.
  6. Similarly, GetEffectiveTopFrameForPartitioning is called, which incorrectly identifies the victim frame as a top-level frame, bypassing cookie partitioning (SameSite/CHIPS) for the victim origin.

Impact

An attacker can force JavaScript execution on origins where the user has explicitly disabled it. Furthermore, it allows an attacker to bypass storage isolation and partitioning, potentially enabling CSRF or information leakage against sites relying on CHIPS or SameSite cookie attributes.

Suggested Fix

The predicates MimeHandlerStreamManager::IsExtensionHost, IsContentHost, and their underlying Is...FrameTreeNodeId helpers should be updated to verify that the embedder_host’s last committed URL matches the original_url stored in the StreamInfo, consistent with the verification performed in GetStreamContainer.

Evaluated with Chrome root at commit: 1a8d40fc44df2088d5945c0bf53584038aa1614a


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.

View on issue tracker