CVE-2026-113204
Overview
Files Changed
chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappVerifier.javachrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/TestVerifier.javachrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/EmptyVerifier.javachrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifier.javachrome/android/javatests/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityCurrentPageVerifierTest.javachrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifier.javachrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/Verifier.javachrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifierTest.javachrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifierTest.java
Original Bug Report
TWA preserves verified no-toolbar UI after navigation to an attacker-origin blob document
Steps to reproduce the problem
Reproduction
The attached APK is a victim-environment harness, not the attacker application. It creates a correctly verified TWA using the supplied assetlinks.json and opens origin A. The attacker capability is limited to the cross-origin iframe served by origin B.
- Install
twa-blob-medium-poc.apkon a device with Chrome 150.0.7871.186. - Serve
site/through two HTTPS origins. Origin A must servetrusted-twa.htmland/.well-known/assetlinks.json; origin B servesattacker.htmlandcollect. - Update the two host constants in
app/app/src/main/java/dev/vrp/twablobpoc/MainActivity.javaand the iframe/fetch URLs in the HTML if different hosts are used, then rebuild the APK. - Launch the app. Confirm that the page opens full-screen as a verified TWA and Chrome displays its normal
Running in Chromedisclosure. - Tap Open protected document once.
- Observe the full-screen Northstar Workspace / Session expired page. There is no URL bar, close button, or origin indicator.
- Enter a dummy value and tap Sign in.
- Tap Show PoC details. The page prints a committed URL beginning with
blob:https://<origin-B>/andDocument origin: https://<origin-B>while Chrome still shows no browser controls.
Direct launch command:
adb shell am start -f 0x10008000 -n dev.vrp.twablobpoc/.MainActivity
Problem Description
Root cause
At CurrentPageVerifier.verify():
Promise<Boolean> result = mDelegate.verify(url);
String scope = mDelegate.getVerifiedScope(url);
if (scope == null) return;
For blob:https://attacker/..., TwaVerifier.verify() correctly produces a fulfilled false result because Origin.create(url) rejects non-HTTP(S) outer schemes. However, TwaVerifier.getVerifiedScope() also returns null. CurrentPageVerifier then returns before consuming the false result and leaves the previous VerificationStatus.SUCCESS state untouched.
SharedActivityCoordinator.appModeUiAllowedFor() treats every state except explicit FAILURE as app mode, and TrustedWebActivityBrowserControlsVisibilityManager consequently keeps browser controls hidden. A secure-inner-origin blob has security level NONE, so the separate DANGEROUS/WARNING fallback does not reveal the toolbar.
Affected functions:
chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifier.java:118chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifier.java:70components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/Origin.java:35chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/SharedActivityCoordinator.java:100chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityBrowserControlsVisibilityManager.java:117chrome/browser/ssl/security_state_tab_helper_browsertest.cc:301
Security impact
An attacker who controls third-party content embedded by a legitimate TWA can replace the complete top-level page with a credential prompt while Chrome conceals the attacker origin. The user makes the security-relevant decision to enter a password because the page still has the legitimate app’s full-screen presentation and no trustworthy origin indicator. In the attached PoC, a dummy password entered into the origin-concealed page is sent to the attacker’s HTTPS origin and received by the PoC server.
The attacker does not need to control the Android app, the verified TWA origin, or its Digital Asset Links file. Those are controlled locally in this self-contained harness only to avoid testing a third-party production TWA. The real-world prerequisite is an unsandboxed third-party iframe, such as an ad, partner widget, or user-controlled embed, inside a legitimate TWA. Exploitation then requires one click inside that frame.
Expected versus actual
Expected: after the top-level document commits an origin-B blob URL, TWA verification changes to FAILURE; Chrome displays the Custom Tab toolbar containing origin B and a close control.
Actual: the old SUCCESS state persists. The attacker page occupies the complete TWA surface indefinitely, and control_container, toolbar, location_bar, and url_bar are all absent.
Additional Comments
Summary
TWA preserves verified no-toolbar UI after navigation to an attacker-origin blob document
Custom Questions
Type of crash:
Crash state:
Reporter credit:
Additional Data
Category: Security
Chrome Channel: Not sure
Regression: N/A \