Chrome · Digital Credentials
CVE-2026-0904
Logic Error in Digital Credentials
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
chrome/browser/digital_credentials/digital_identity_provider_desktop.ccchrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.cc
Patch
From 9f349d7e49bf8f162840ce82f3368fc81996ff16 Mon Sep 17 00:00:00 2001 From: Mohamed Amir Yosef <[email protected]> Date: Mon, 03 Nov 2025 11:08:40 -0800 Subject: [PATCH] [DC] Elide the origin for display in the interstitial This CL properly elides the origins to be displayed in the digital credentials UIs. More details are in the linked bug. Bug: 452209495 Change-Id: Icdf97292f42b91c7911a0397c7f40ab0659f1b82 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7083387 Reviewed-by: Elly FJ <[email protected]> Commit-Queue: Mohamed Amir Yosef <[email protected]> Cr-Commit-Position: refs/heads/main@{#1539496} --- diff --git a/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc b/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc index 9e426ed4..d84f860b 100644 --- a/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc +++ b/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc @@ -36,6 +36,9 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/theme_tracking_animated_image_view.h" #include "ui/views/layout/box_layout_view.h" +#include "ui/views/layout/layout_provider.h" +#include "ui/views/style/typography.h" +#include "ui/views/style/typography_provider.h" #include "ui/views/widget/widget.h" namespace { @@ -284,10 +287,21 @@ dialog_body_id = IDS_WEB_DIGITAL_CREDENTIALS_ISSUANCE_QR_BODY; break; } - std::u16string dialog_body = l10n_util::GetStringFUTF16( - dialog_body_id, - url_formatter::FormatOriginForSecurityDisplay( - rp_origin_, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); + const views::LayoutProvider* layout_provider = views::LayoutProvider::Get(); + // The dialog content width is used as an approximation of the available + // width for the origin. + const int dialog_width = layout_provider->GetDistanceMetric( + views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH); + const gfx::Insets dialog_insets = + layout_provider->GetInsetsMetric(views::INSETS_DIALOG); + const float content_width = dialog_width - dialog_insets.width(); + const gfx::FontList& font_list = views::TypographyProvider::Get().GetFont( + views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY); + std::u16string formatted_origin = + url_formatter::ElideUrl(rp_origin_.GetURL(), font_list, content_width); + + std::u16string dialog_body = + l10n_util::GetStringFUTF16(dialog_body_id, formatted_origin); EnsureDialogCreated()->TryShow( /*accept_button=*/std::nullopt, base::OnceClosure(), /*cancel_button=*/ diff --git a/chrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.cc b/chrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.cc index 5c56236..27298d4a 100644 --- a/chrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.cc +++ b/chrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.cc @@ -18,6 +18,10 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/dialog_model.h" #include "ui/base/mojom/dialog_button.mojom.h" +#include "ui/display/screen.h" +#include "ui/views/layout/layout_provider.h" +#include "ui/views/style/typography.h" +#include "ui/views/style/typography_provider.h" #include "ui/views/widget/widget.h" using DialogButton = ui::DialogModel::Button; @@ -106,9 +110,17 @@ bool positive_button_enabled = !was_request_aborted; + const views::LayoutProvider* layout_provider = views::LayoutProvider::Get(); + const int dialog_width = layout_provider->GetDistanceMetric( + views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH); + const gfx::Insets dialog_insets = + layout_provider->GetInsetsMetric(views::INSETS_DIALOG); + const float content_width = dialog_width - dialog_insets.width(); + + const gfx::FontList& font_list = views::TypographyProvider::Get().GetFont( + views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_PRIMARY); std::u16string formatted_origin = - url_formatter::FormatOriginForSecurityDisplay( - rp_origin_, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); + url_formatter::ElideUrl(rp_origin_.GetURL(), font_list, content_width); std::u16string body_text = l10n_util::GetStringFUTF16(body_resource_id, formatted_origin); std::u16string positive_button_label = l10n_util::GetStringUTF16(
Loading diff…
Original Bug Report
reported by [email protected]
truncated long domain on Digital Credentials API prompt lead to spoof
VULNERABILITY DETAILS
When the Digital Credentials API dialog is invoked, the dialog appears with the name “Do you trust this site with your data” and the long domain name causes the domain name to be truncated. As seen in the second video at https://developer.chrome.com/blog/digital-credentials-api-shipped?hl=en . In the second video, the dialog appears to be “9000–firebase-studio-1758636784187.cluster-64pjnskmlbaxowh5lzq6i7v4ra.clo” instead of 9000–firebase-studio-1758636784187.cluster-64pjnskmlbaxowh5lzq6i7v4ra.cloudworkstations.dev, thus causing the dialog to be spoofed.
- Create a Digital Credentials API application using the example at https://developer.chrome.com/blog/digital-credentials-api-shipped?hl=en using a long domain.
- Open the page as shown on https://verifier.multipaz.org/ and click one of the button and show the confirm dialog
References
On This Page