Chrome · Downloads
CVE-2025-9867
Logic Error in Downloads
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
DangerousDownloadDialogBridgechrome/browser/download/android/dangerous_download_dialog_bridge.cc |
modified | |
ifchrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.java |
modified |
Files Changed
chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadDialogIncognitoTest.javachrome/browser/download/android/dangerous_download_dialog_bridge.ccchrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.javachrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java
Patch
From b2bf216dc223e333700a470b55df72ffeba66c6d Mon Sep 17 00:00:00 2001
From: Lily Chen <chlily@chromium.org>
Date: Wed, 02 Jul 2025 12:17:41 -0700
Subject: [PATCH] Improve DangerousDownloadDialog message
This CL improves the message string shown in DangerousDownloadDialog to
more accurately convey security-relevant information to the user.
* Puts the filename in quotation marks and adds bold font, to make it
clearer that the filename portion is site-controlled and delineate it
from adjacent Chrome-produced parts of the UI string. The use of bold
font is consistent with the iOS download dialog, updated in
crrev.com/c/6633364.
* Adds the domain of the download URL to the string if available, in a
colored font. This domain string is currently the download URL,
processed through elide_url formatting functions, but we may select a
more representative URL or origin in the future.
Screenshots:
https://drive.google.com/drive/folders/10U4_bv9OZxIpCOCR3pPdJE9PC1MIg5Ve
Bug: 415496161, 410721828
Change-Id: I5366c4f95350e0bbabda25f004288b760213da20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6696592
Reviewed-by: Xinghui Lu <xinghuilu@chromium.org>
Commit-Queue: Lily Chen <chlily@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1481797}
---
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadDialogIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadDialogIncognitoTest.java
index 7c59973..41667efc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadDialogIncognitoTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadDialogIncognitoTest.java
@@ -44,6 +44,7 @@
private static final String DOWNLOAD_PATH = "/android/Download";
private static final String PAGE_URL = "www.pageurl.com/download";
private static final String FILE_NAME = "download.pdf";
+ private static final String DOWNLOAD_DOMAIN = "pageurl.com";
public static final int ICON_ID = R.drawable.btn_close;
@Rule
@@ -179,6 +180,7 @@
mModalDialogManager,
FILE_NAME,
TOTAL_BYTES,
+ DOWNLOAD_DOMAIN,
ICON_ID,
mResultCallback);
});
diff --git a/chrome/browser/download/android/dangerous_download_dialog_bridge.cc b/chrome/browser/download/android/dangerous_download_dialog_bridge.cc
index 100df18c..7039954 100644
--- a/chrome/browser/download/android/dangerous_download_dialog_bridge.cc
+++ b/chrome/browser/download/android/dangerous_download_dialog_bridge.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/android/resource_mapper.h"
#include "chrome/browser/download/android/download_dialog_utils.h"
#include "chrome/grit/generated_resources.h"
+#include "components/url_formatter/elide_url.h"
#include "ui/android/window_android.h"
#include "ui/base/l10n/l10n_util.h"
@@ -25,6 +26,15 @@
using base::android::ConvertJavaStringToUTF8;
using base::android::JavaParamRef;
+namespace {
+// Gets the "download domain" string shown in the dialog. Currently, this is
+// derived from the download URL.
+std::u16string GetDownloadDomain(download::DownloadItem* item) {
+ return url_formatter::FormatUrlForDisplayOmitSchemePathAndTrivialSubdomains(
+ item->GetURL());
+}
+} // namespace
+
DangerousDownloadDialogBridge::DangerousDownloadDialogBridge() {
JNIEnv* env = base::android::AttachCurrentThread();
java_object_.Reset(Java_DangerousDownloadDialogBridge_create(
@@ -59,6 +69,8 @@
download_item->GetGuid(),
base::UTF8ToUTF16(download_item->GetFileNameToReportUser().value()),
download_item->GetTotalBytes(),
+ base::android::ConvertUTF16ToJavaString(env,
+ GetDownloadDomain(download_item)),
ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_INFOBAR_WARNING));
}
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.java
index 350a718..dbaabb4a 100644
--- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.java
+++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/DangerousDownloadDialogBridge.java
@@ -45,6 +45,7 @@
* @param guid GUID of the download.
* @param fileName Name of the download file.
* @param totalBytes Total bytes of the file.
+ * @param downloadDomain Domain name to associate with the downloaded file.
* @param iconId The icon resource for the warning dialog.
*/
@CalledByNative
@@ -53,6 +54,7 @@
@JniType("std::string") String guid,
@JniType("std::u16string") String fileName,
long totalBytes,
+ String downloadDomain,
int iconId) {
Activity activity = windowAndroid.getActivity().get();
if (activity == null) {
@@ -66,6 +68,7 @@
((ModalDialogManagerHolder) activity).getModalDialogManager(),
fileName,
totalBytes,
+ downloadDomain,
iconId,
(accepted) -> {
if (accepted) {
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java
index 0c31593..34eb503 100644
--- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java
+++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DangerousDownloadDialog.java
@@ -5,6 +5,12 @@
package org.chromium.chrome.browser.download.dialogs;
import android.content.Context;
+import android.graphics.Typeface;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
import androidx.annotation.IntDef;
import androidx.core.content.res.ResourcesCompat;
@@ -13,6 +19,7 @@
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.build.annotations.NullMarked;
import org.chromium.chrome.browser.download.R;
+import org.chromium.components.browser_ui.styles.SemanticColorUtils;
import org.chromium.components.browser_ui.util.DownloadUtils;
import org.chromium.ui.UiUtils;
import org.chromium.ui.modaldialog.DialogDismissalCause;
@@ -55,31 +62,25 @@
/**
* Called to show a warning dialog for dangerous download.
+ *
* @param context Context for showing the dialog.
* @param modalDialogManager Manager for managing the modal dialog.
* @param fileName Name of the download file.
* @param totalBytes Total bytes of the file.
+ * @param downloadDomain Domain name to associate with the downloaded file.
* @param iconId Icon ID of the warning dialog.
* @param callback Callback to run when confirming the download, true for accept the download,
- * false otherwise.
+ * false otherwise.
*/
public void show(
Context context,
ModalDialogManager modalDialogManager,
String fileName,
long totalBytes,
+ String downloadDomain,
int iconId,
Callback<Boolean> callback) {
var resources = context.getResources();
- String message =
- totalBytes > 0
- ? resources.getString(R.string.dangerous_download_dialog_text, fileName)
- : resources.getString(
- R.string.dangerous_download_dialog_text_with_size,
- fileName,
- DownloadUtils.getStringForBytes(context, totalBytes));
- ArrayList<CharSequence> message_paragraphs = new ArrayList<>(List.of(message));
-
var controller =
new ModalDialogProperties.Controller() {
@Override
@@ -112,13 +113,16 @@
}
}
};
+
PropertyModel propertyModel =
new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
.with(ModalDialogProperties.CONTROLLER, controller)
.with(
ModalDialogProperties.TITLE,
resources.getString(R.string.dangerous_download_dialog_title))
- .with(ModalDialogProperties.MESSAGE_PARAGRAPHS, message_paragraphs)
+ .with(
+ ModalDialogProperties.MESSAGE_PARAGRAPHS,
+ getMessageParagraphs(context, fileName, totalBytes, downloadDomain))
.with(
ModalDialogProperties.POSITIVE_BUTTON_TEXT,
resources.getString(
@@ -143,6 +147,64 @@
}
/**
+ * Selects the appropriate message string template and inserts formatted substitutions.
+ *
Loading diff…
Original Bug Report
reported by fr...@gmail.com
"File might be harmful" dialog does not have origin
Steps to reproduce the problem
- Access poc.html
- Click the button
- The download pop-up will still appear on https://google.com
Problem Description
This vulnerability occurs when there is a condition that a file download pop-up origin can be overlaid on other origin. The file download pop-up should only be appear when user is accessing the real origin where the file download pop-up come from.
For more information you can read on crbug.com/40055527
Chrome version: 135.0.7049.111 (Official Build) (64-bit)
Summary
crbug.com/40055527 is still reproducible on newest version of Chrome
Additional Data
Category: Security
Chrome Channel: Not sure
Regression: Yes
References
On This Page