Display precursor origins when applicable in external protocol dialog
External protocol dialogs display the origin that initiated the
external protocol request. The initiating origin helps the user
attribute the request to a particular site, so that they can decide if
they can trust that site to launch an external application. When the
initiating origin was opaque (such as from a sandboxed iframe), the
dialog would display no origin or a generic message, so the user
didn't have any information for making a trust decision. This CL
converts the initiating origin to its precursor origin (the origin
that created the initiating origin) when creating the external
protocol dialog. Displaying the precursor origin gives the user more
useful information for making a trust decision.
Bug: 1041749
Change-Id: I0b21d20e13d7d71db361746dbb18df8d980339bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2063420
Commit-Queue: Emily Stark <[email protected]>
Reviewed-by: Mustafa Emre Acer <[email protected]>
Cr-Commit-Position: refs/heads/master@{#742492}
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc
index 3af4b53b..e4f2b124 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -316,13 +316,27 @@
g_accept_requests = false;
+ base::Optional<url::Origin> initiating_origin_or_precursor;
+ if (initiating_origin) {
+ // Transform the initiating origin to its precursor origin if it is
+ // opaque. |initiating_origin| is shown in the UI to attribute the external
+ // protocol request to a particular site, and showing an opaque origin isn't
+ // useful.
+ if (initiating_origin->opaque()) {
+ initiating_origin_or_precursor = url::Origin::Create(
+ initiating_origin->GetTupleOrPrecursorTupleIfOpaque().GetURL());
+ } else {
+ initiating_origin_or_precursor = initiating_origin;
+ }
+ }
+
// The worker creates tasks with references to itself and puts them into
// message loops.
- shell_integration::DefaultWebClientWorkerCallback callback =
- base::Bind(&OnDefaultProtocolClientWorkerFinished, escaped_url,
- render_process_host_id, render_view_routing_id,
- block_state == UNKNOWN, page_transition, has_user_gesture,
- initiating_origin, g_external_protocol_handler_delegate);
+ shell_integration::DefaultWebClientWorkerCallback callback = base::Bind(
+ &OnDefaultProtocolClientWorkerFinished, escaped_url,
+ render_process_host_id, render_view_routing_id, block_state == UNKNOWN,
+ page_transition, has_user_gesture, initiating_origin_or_precursor,
+ g_external_protocol_handler_delegate);
// Start the check process running. This will send tasks to a worker task
// runner and when the answer is known will send the result back to