Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in PDF
DescriptionInsufficient policy enforcement in PDF
ComponentPDF
Bug ClassLogic Error
Tracker478296121
Fix commit2265687230f6 (chromium/src) +65/-6
CISA KEVNot listed
CreditedAyato Shitomi
Disclosed2026-03-10

Changed Functions

FunctionChangeNotes
if
chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
modified
if
chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java
modified

Files Changed

  • chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
  • chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
  • chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java
  • chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtilsUnitTest.java
From 2265687230f6a3642e766a68d7c3b201ced0bbf6 Mon Sep 17 00:00:00 2001
From: Shu Yang <[email protected]>
Date: Fri, 06 Feb 2026 13:32:39 -0800
Subject: [PATCH] Restrict PDF re-downloads to safe schemes and preserve initiator

Going back to a PDF URL may require a re-download, and this can be
triggered when the current page is not a PDF. Ensure that these
navigations can't elevate their privileges by limiting to HTTP(S)
and preserving information about the initiator.

Bug: 478296121
Change-Id: Ic08a4aa797b0ba11f7010714570e4e9d3be31a48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7520272
Reviewed-by: Charlie Reis <[email protected]>
Reviewed-by: Sirisha Kavuluru <[email protected]>
Commit-Queue: Shu Yang <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1581094}
---

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
index ae0b4dee..95f7a504 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -112,6 +112,7 @@
 import org.chromium.ui.base.ViewAndroidDelegate;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.url.GURL;
+import org.chromium.url.Origin;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -1854,8 +1855,15 @@
      * @param url The URL that was loaded.
      * @param transitionType The transition type to the current URL.
      * @param isPdf Whether the navigation is for PDF content.
+     * @param isRendererInitiated Whether the navigation is initiated by renderer.
+     * @param initiatorOrigin The Origin that initiated this navigation.
      */
-    void handleDidFinishNavigation(GURL url, int transitionType, boolean isPdf) {
+    void handleDidFinishNavigation(
+            GURL url,
+            int transitionType,
+            boolean isPdf,
+            boolean isRendererInitiated,
+            @Nullable Origin initiatorOrigin) {
         mIsNativePageCommitPending = false;
         boolean isReload = (transitionType & PageTransition.CORE_MASK) == PageTransition.RELOAD;
         // Set isPdf param based on the url. This is because the isPdf param in NavigationHandle is
@@ -1866,11 +1874,20 @@
                 PdfUtils.shouldOpenPdfInline(isIncognito())
                         && PdfUtils.isDownloadedPdf(url.getSpec());
         if (!maybeShowNativePage(url.getSpec(), isReload, isPdf ? new PdfInfo() : null)) {
-            String downloadUrl = PdfUtils.decodePdfPageUrl(url.getSpec());
+            // This is restricted to HTTP(S) URLs specifically, as these are the only schemes that
+            // necessitate a PDF re-download.
+            String downloadUrl = PdfUtils.getPdfReDownloadUrl(url.getSpec());
             if (downloadUrl != null) {
-                // When the download url is not null, we are on a pdf native page which requires
-                // re-download. Load the download url to trigger the re-download.
-                loadUrl(new LoadUrlParams(downloadUrl));
+                // When the download url is not null, we are navigating to a pdf native page which
+                // requires re-download. Load the download url to trigger the re-download.
+                var param = new LoadUrlParams(downloadUrl);
+                // To avoid a SameSite=strict cookie bypass, it is important to preserve whether the
+                // navigation was renderer initiated and what its initiator origin was.
+                param.setIsRendererInitiated(isRendererInitiated);
+                if (initiatorOrigin != null) {
+                    param.setInitiatorOrigin(initiatorOrigin);
+                }
+                loadUrl(param);
             } else {
                 showRenderedPage();
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
index eec3439..18b339eb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -318,7 +318,11 @@
 
             mTab.updateTitle();
             mTab.handleDidFinishNavigation(
-                    navigation.getUrl(), navigation.pageTransition(), navigation.isPdf());
+                    navigation.getUrl(),
+                    navigation.pageTransition(),
+                    navigation.isPdf(),
+                    navigation.isRendererInitiated(),
+                    navigation.getInitiatorOrigin());
             mTab.setIsShowingErrorPage(navigation.isErrorPage());
 
             // TODO(crbug.com/40264745) remove this call. onUrlUpdated should have been called
diff --git a/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java b/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java
index 61383fa..222a9473 100644
--- a/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java
+++ b/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtils.java
@@ -316,6 +316,30 @@
     }
 
     /**
+     * Extracts a valid HTTP(S) URL from a PDF page URL for re-downloading.
+     *
+     * <p>This method decodes the provided {@code originalUrl} and verifies that the result uses a
+     * supported scheme (HTTP or HTTPS).
+     *
+     * @param originalUrl The original, potentially encoded, URL string to process.
+     * @return The decoded URL string if it is a valid HTTP(S) URL; {@code null} otherwise.
+     */
+    public static @Nullable String getPdfReDownloadUrl(String originalUrl) {
+        String decodedUrl = decodePdfPageUrl(originalUrl);
+
+        if (decodedUrl == null) {
+            return null;
+        }
+
+        if (decodedUrl.startsWith(UrlConstants.HTTP_URL_PREFIX)
+                || decodedUrl.startsWith(UrlConstants.HTTPS_URL_PREFIX)) {
+            return decodedUrl;
+        }
+
+        return null;
+    }
+
+    /**
      * Encode content uri if it is PDF MIME type.
      *
      * @param uri The uri to be encoded.
diff --git a/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtilsUnitTest.java b/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtilsUnitTest.java
index 91d1c9c..86c1629 100644
--- a/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtilsUnitTest.java
+++ b/chrome/browser/ui/android/pdf/java/src/org/chromium/chrome/browser/pdf/PdfUtilsUnitTest.java
@@ -49,6 +49,8 @@
     private static final String PDF_BLOB_URL = "blob:https://www.foo.com/abc";
     private static final String PDF_LINK_ENCODED =
             "chrome-native://pdf/link?url=https%3A%2F%2Fwww.foo.com%2Ftestfiles%2Fpdf%2Fsample.pdf";
+    private static final String PDF_LINK_ENCODED_INVALID =
+            "chrome-native://pdf/link?url=chrome%3A%2F%2Fversion";
     private static final String FILE_PATH = "/media/external/downloads/sample.pdf";
     private static final String FILE_NAME = "sample.pdf";
     private static final String IMAGE_FILE_URL = "file:///media/external/downloads/sample.jpg";
@@ -238,6 +240,18 @@
     }
 
     @Test
+    public void testGetPdfReDownloadUrl_Https() {
+        String downloadUrl = PdfUtils.getPdfReDownloadUrl(PDF_LINK_ENCODED);
+        Assert.assertEquals("The re-download url should match", PDF_LINK, downloadUrl);
+    }
+
+    @Test
+    public void testGetPdfReDownloadUrl_Invalid() {
+        String downloadUrl = PdfUtils.getPdfReDownloadUrl(PDF_LINK_ENCODED_INVALID);
+        Assert.assertNull("The re-download url should be null", downloadUrl);
+    }
+
+    @Test
     public void testEncodeDecodeUrlWithSpecialCharacter() {
         String encodedUrl = PdfUtils.encodePdfPageUrl(CONTENT_URL_SPECIAL_CHARACTER);
         String decodedUrl = PdfUtils.decodePdfPageUrl(encodedUrl);
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.