Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactConfused deputy in BackgroundFetch
DescriptionConfused deputy in BackgroundFetch
ComponentBackgroundFetch
Bug ClassLogic Error
Tracker495444970
Fix commit8046f4cc56ed (chromium/src) +77/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-09-08

Changed Functions

FunctionChangeNotes
for
content/browser/background_fetch/background_fetch_service_impl.cc
modified
if
content/browser/background_fetch/background_fetch_service_impl.cc
modified
TEST_F
content/browser/background_fetch/background_fetch_service_unittest.cc
modified

Files Changed

  • content/browser/background_fetch/background_fetch_service_impl.cc
  • content/browser/background_fetch/background_fetch_service_unittest.cc
From 8046f4cc56ed8aebe6c9aa4838f5ae6b1ba07764 Mon Sep 17 00:00:00 2001
From: Nidhi Jaju <nidhijaju@chromium.org>
Date: Fri, 07 Aug 2026 04:08:03 -0700
Subject: [PATCH] [BackgroundFetch] Validate request URL scheme in the browser

BackgroundFetchManager in the renderer rejects request URLs that do not
use a HTTP(S) scheme. Mirror that check in
BackgroundFetchServiceImpl::ValidateRequests() so the browser process
does not forward such requests to the download subsystem, which would
otherwise treat them as trusted browser requests.

Bug: 495444970
Change-Id: If25e925d5d7e19a9d53453971933dc0d10d9a4a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8200209
Commit-Queue: Peter Beverloo <peter@chromium.org>
Auto-Submit: Nidhi Jaju <nidhijaju@chromium.org>
Reviewed-by: Peter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1675631}
---

diff --git a/content/browser/background_fetch/background_fetch_service_impl.cc b/content/browser/background_fetch/background_fetch_service_impl.cc
index f2e3d9f..97f0ba9 100644
--- a/content/browser/background_fetch/background_fetch_service_impl.cc
+++ b/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -222,6 +222,24 @@
     return false;
   }
 
+  // Ensure all requests are valid and use the HTTP or HTTPS scheme.
+  for (const auto& request : requests) {
+    if (!request) {
+      mojo::ReportBadMessage("Null request");
+      return false;
+    }
+
+    if (!request->url.is_valid()) {
+      mojo::ReportBadMessage("Invalid request URL");
+      return false;
+    }
+
+    if (!request->url.SchemeIsHTTPOrHTTPS()) {
+      mojo::ReportBadMessage("Invalid request URL scheme");
+      return false;
+    }
+  }
+
   return true;
 }
 
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc
index 287e7ec5..9fb5ec3a 100644
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -493,11 +493,69 @@
     blink::mojom::BackgroundFetchRegistrationPtr registration;
 
     Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
-          std::move(requests), std::move(options), SkBitmap(), &error,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
           &registration);
     ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
     EXPECT_EQ("Invalid requests", bad_message_observer.WaitForBadMessage());
   }
+
+  // Request URLs must use the HTTP or HTTPS scheme.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    auto request = CreateRequestWithProvidedResponse(
+        "GET", GURL("file:///test.txt"),
+        TestResponseBuilder(200).MakeIndefinitelyPending().Build());
+    requests.push_back(std::move(request));
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Invalid request URL scheme",
+              bad_message_observer.WaitForBadMessage());
+  }
+
+  // Request URLs must be valid URLs.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    auto request = CreateRequestWithProvidedResponse(
+        "GET", GURL("invalid-url"),
+        TestResponseBuilder(200).MakeIndefinitelyPending().Build());
+    requests.push_back(std::move(request));
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Invalid request URL", bad_message_observer.WaitForBadMessage());
+  }
+
+  // Request objects in the vector must be non-null.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    requests.push_back(nullptr);
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), std::move(options), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Null request", bad_message_observer.WaitForBadMessage());
+  }
 }
 
 TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) {
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc
index 287e7ec5..9fb5ec3a 100644
--- a/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -493,11 +493,69 @@
     blink::mojom::BackgroundFetchRegistrationPtr registration;
 
     Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
-          std::move(requests), std::move(options), SkBitmap(), &error,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
           &registration);
     ASSERT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
     EXPECT_EQ("Invalid requests", bad_message_observer.WaitForBadMessage());
   }
+
+  // Request URLs must use the HTTP or HTTPS scheme.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    auto request = CreateRequestWithProvidedResponse(
+        "GET", GURL("file:///test.txt"),
+        TestResponseBuilder(200).MakeIndefinitelyPending().Build());
+    requests.push_back(std::move(request));
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Invalid request URL scheme",
+              bad_message_observer.WaitForBadMessage());
+  }
+
+  // Request URLs must be valid URLs.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    auto request = CreateRequestWithProvidedResponse(
+        "GET", GURL("invalid-url"),
+        TestResponseBuilder(200).MakeIndefinitelyPending().Build());
+    requests.push_back(std::move(request));
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), options.Clone(), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Invalid request URL", bad_message_observer.WaitForBadMessage());
+  }
+
+  // Request objects in the vector must be non-null.
+  {
+    mojo::FakeMessageDispatchContext fake_dispatch_context;
+    mojo::test::BadMessageObserver bad_message_observer;
+    std::vector<blink::mojom::FetchAPIRequestPtr> requests;
+    requests.push_back(nullptr);
+
+    blink::mojom::BackgroundFetchError error;
+    blink::mojom::BackgroundFetchRegistrationPtr registration;
+
+    Fetch(/* service_worker_registration_id= */ 42, kExampleDeveloperId,
+          std::move(requests), std::move(options), SkBitmap(), &error,
+          &registration);
+    EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ARGUMENT);
+    EXPECT_EQ("Null request", bad_message_observer.WaitForBadMessage());
+  }
 }
 
 TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) {
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.