Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in Chrome for iOS
DescriptionInsufficient validation of untrusted input in Chrome for iOS
ComponentChrome for iOS
Bug ClassLogic Error
Tracker517312048
Fix commit2971e9b63cf2 (chromium/src) +3/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-07-29

Files Changed

  • ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
From 2971e9b63cf2938ab3f1f471857e878337c50f70 Mon Sep 17 00:00:00 2001
From: Stepan Khapugin <stkhapugin@chromium.org>
Date: Fri, 05 Jun 2026 07:15:16 -0700
Subject: [PATCH] [iOS][Lens] Only allow HTTP(s) navigation from Chromnient.

Ignore non-HTTP(s) loads from chromnient.

Bug: 517312048
Change-Id: Id069035e7c832dc802138351622d8f0fb56c6143
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7903263
Commit-Queue: Stepan Khapugin <stkhapugin@chromium.org>
Auto-Submit: Stepan Khapugin <stkhapugin@chromium.org>
Commit-Queue: Radu Nitescu <radunitescu@google.com>
Reviewed-by: Radu Nitescu <radunitescu@google.com>
Cr-Commit-Position: refs/heads/main@{#1642314}
---

diff --git a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
index 7cefc82d0..2fca4fd 100644
--- a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
+++ b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
@@ -321,6 +321,9 @@
 
 - (void)lensOverlay:(id<ChromeLensOverlay>)lensOverlay
     didRequestToOpenURL:(GURL)URL {
+  if (!URL.SchemeIsHTTPOrHTTPS()) {
+    return;
+  }
   [self.resultConsumer loadResultsURL:URL httpHeaders:nil];
 }
 
Loading diff…

Original Bug Report

reported by aw...@chromium.org

Potential navigation laundering via missing scheme validation in iOS Lens Overlay

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: The iOS Lens Overlay feature fails to validate URL schemes when a user opens a link detected within an image, such as a QR code. If the URL uses a restricted scheme like chrome://, the Lens Result Page rejects the load but gracefully falls back to opening it in a new tab using a trusted, browser-initiated command. This potentially allows an attacker to bypass web-content restrictions and load privileged schemes if a user scans and taps a malicious visual entity.

Affected files:

  • ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
  • ios/chrome/browser/lens_overlay/coordinator/lens_result_page_mediator.mm
  • ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm

Estimated timestamp from git blame: 2024-09-18

Summary

There is a potential navigation laundering vulnerability in the iOS Lens Overlay feature due to missing scheme validation. When the Google Lens SDK detects a URL (e.g., in a QR code) and the user requests to open it, the URL is passed to the browser without verifying that it uses an http:// or https:// scheme. Through a fallback mechanism intended for external links, the unvalidated URL is eventually opened using an internal command that flags the navigation as trusted (fromChrome = YES), bypassing standard web-initiated navigation restrictions.

Vulnerability Details

When a user interacts with a detected URL in the Lens Overlay, the SDK invokes the delegate method lensOverlay:didRequestToOpenURL: in ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm. This method passes the unvalidated URL directly to the result consumer:

// ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
- (void)lensOverlay:(id<ChromeLensOverlay>)lensOverlay
    didRequestToOpenURL:(GURL)URL {
  [self.resultConsumer loadResultsURL:URL httpHeaders:nil];
}

This behavior contrasts with the sibling LensViewFinderCoordinator, which correctly checks url.SchemeIsHTTPOrHTTPS() before processing the URL.

Once passed to LensResultPageMediator -loadResultsURL:, the URL attempts to load in the Lens result web view. This triggers the policy decider shouldAllowRequest:requestInfo:decisionHandler:. Because a restricted URL (like chrome://version) is not a valid Google host, IsValidURLToOpenInResultsPage(URL) returns NO.

To handle the rejected URL, the LensResultPageMediator cancels the navigation but requests the coordinator to open the URL in a new tab instead:

// ios/chrome/browser/lens_overlay/coordinator/lens_result_page_mediator.mm
    decisionHandler(web::WebStatePolicyDecider::PolicyDecision::Cancel());
    // ...
    [self.delegate lensResultPageOpenURLInNewTabRequested:URL];

This request is routed to LensOverlayCoordinator -openURLInNewTab:, which creates an OpenNewTabCommand using a specific initializer:

// ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm
- (void)openURLInNewTab:(GURL)URL {
  OpenNewTabCommand* command =
      [OpenNewTabCommand commandWithURLFromChrome:URL
                                      inIncognito:self.isOffTheRecord];
  // ...
}

The commandWithURLFromChrome: initializer explicitly sets the fromChrome property to YES. When the URL loading service processes this command, it treats the navigation as a trusted, browser-initiated action (mapping to ui::PAGE_TRANSITION_TYPED with is_renderer_initiated = false). This elevated trust level allows the navigation to bypass the security restrictions that normally prevent web content from navigating to chrome://, data://, or file:// URIs.

Potential Reproduction Steps

Note: These are suggested/potential steps to reproduce the issue, as our tooling agent does not currently have the ability to run code or execute a live proof-of-concept.

  1. An attacker hosts a webpage containing a visual entity, such as a QR code or styled text, that encodes a restricted URL (e.g., chrome://version).
  2. The user navigates to this webpage in Chrome on iOS.
  3. The user triggers the Lens Overlay feature (e.g., via the omnibox Lens icon).
  4. The user taps the detected entity in the overlay and selects the option to open the URL.
  5. The browser rejects the URL in the bottom sheet but launders it into a new tab as a trusted navigation, successfully loading the restricted scheme.

Suggested Fix

The LensOverlayMediator should validate the URL scheme before passing it to the result consumer. This can be fixed by adding a check identical to the one found in LensViewFinderCoordinator:

// ios/chrome/browser/lens_overlay/coordinator/lens_overlay_mediator.mm
- (void)lensOverlay:(id<ChromeLensOverlay>)lensOverlay
    didRequestToOpenURL:(GURL)URL {
  if (!URL.SchemeIsHTTPOrHTTPS()) {
    return;
  }
  [self.resultConsumer loadResultsURL:URL httpHeaders:nil];
}

Evaluated with Chrome root at commit: 61b554d1173664781b13575139fa988a5abda714


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.

Note: This bug has been automatically redirected to the top-level Chromium component. Please move it to the actual component: https://b.corp.google.com/components/1457074 once PoCs have been generated.

View on issue tracker