Commit efa4867f authored by Han Leon's avatar Han Leon Committed by Commit Bot

[ServiceWorker] Report bad message on receiving Client#{*} calls from a cross-origin client

All JavaScript Client objects seen in a service worker execution context
must be matching origin with the service worker (See the bellowing
explanation in details), so, if the browser-side received a
Client#{postMessage,focus,navigate} call from a cross-origin Client
object, it should be treated as a bad message.

A detailed explanation:
Once a JavaScript Client object has been gotten by the
ServiceWorkerGlobalScope (via ServiceWorkerGlobalScope#{Clients,Client}
APIs), the corresponding window client navigation (including page
redirects) must have already completed and its origin should be matching
with the service worker.
And, for a window client, once the initial navigation done, its document
url won't be changed any more, so its origin should keep matching with
the service worker through its lifetime.
Even in case that the window starts to navigate to another url, a new
ServiceWorkerProviderHost with a new client uuid will be created for
that, without any changes to document url of the original
ServiceWorkerProviderHost.
As above, we're sure a Client#{*} request received in browser-side must
be for a client matching origin with the sender service worker.

BUG=772793

Change-Id: I821c8cced03288596988d583637157e8f1839b2b
Reviewed-on: https://chromium-review.googlesource.com/956111
Commit-Queue: Han Leon <leon.han@intel.com>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542750}
parent a77029c4
...@@ -1120,6 +1120,10 @@ void ServiceWorkerVersion::GetClient(const std::string& client_uuid, ...@@ -1120,6 +1120,10 @@ void ServiceWorkerVersion::GetClient(const std::string& client_uuid,
if (!provider_host || if (!provider_host ||
provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) { provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) {
// The promise will be resolved to 'undefined'. // The promise will be resolved to 'undefined'.
// Note that we don't BadMessage here since Clients#get() can be passed an
// arbitrary UUID. The BadMessages for the origin mismatches below are
// appropriate because the UUID is taken directly from a Client object so we
// expect it to be valid.
std::move(callback).Run(nullptr); std::move(callback).Run(nullptr);
return; return;
} }
...@@ -1166,15 +1170,16 @@ void ServiceWorkerVersion::FocusClient(const std::string& client_uuid, ...@@ -1166,15 +1170,16 @@ void ServiceWorkerVersion::FocusClient(const std::string& client_uuid,
return; return;
} }
if (provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) { if (provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) {
// The client does not belong to the same origin as this ServiceWorker, mojo::ReportBadMessage(
// possibly due to timing issue or bad message. "Received WindowClient#focus() request for a cross-origin client.");
std::move(callback).Run(nullptr /* client */); binding_.Close();
return; return;
} }
if (provider_host->client_type() != if (provider_host->client_type() !=
blink::mojom::ServiceWorkerClientType::kWindow) { blink::mojom::ServiceWorkerClientType::kWindow) {
// focus() should be called only for WindowClient. // focus() should be called only for WindowClient.
mojo::ReportBadMessage("Received focus() request for a non-window client."); mojo::ReportBadMessage(
"Received WindowClient#focus() request for a non-window client.");
binding_.Close(); binding_.Close();
return; return;
} }
...@@ -1219,6 +1224,20 @@ void ServiceWorkerVersion::NavigateClient(const std::string& client_uuid, ...@@ -1219,6 +1224,20 @@ void ServiceWorkerVersion::NavigateClient(const std::string& client_uuid,
std::string("The client was not found.")); std::string("The client was not found."));
return; return;
} }
if (provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) {
mojo::ReportBadMessage(
"Received WindowClient#navigate() request for a cross-origin client.");
binding_.Close();
return;
}
if (provider_host->client_type() !=
blink::mojom::ServiceWorkerClientType::kWindow) {
// navigate() should be called only for WindowClient.
mojo::ReportBadMessage(
"Received WindowClient#navigate() request for a non-window client.");
binding_.Close();
return;
}
if (provider_host->active_version() != this) { if (provider_host->active_version() != this) {
std::move(callback).Run( std::move(callback).Run(
false /* success */, nullptr /* client */, false /* success */, nullptr /* client */,
...@@ -1372,8 +1391,7 @@ void ServiceWorkerVersion::OnPostMessageToClient( ...@@ -1372,8 +1391,7 @@ void ServiceWorkerVersion::OnPostMessageToClient(
message) { message) {
if (!context_) if (!context_)
return; return;
TRACE_EVENT1("ServiceWorker", TRACE_EVENT1("ServiceWorker", "ServiceWorkerVersion::OnPostMessageToClient",
"ServiceWorkerVersion::OnPostMessageToDocument",
"Client id", client_uuid); "Client id", client_uuid);
ServiceWorkerProviderHost* provider_host = ServiceWorkerProviderHost* provider_host =
context_->GetProviderHostByClientID(client_uuid); context_->GetProviderHostByClientID(client_uuid);
...@@ -1382,8 +1400,9 @@ void ServiceWorkerVersion::OnPostMessageToClient( ...@@ -1382,8 +1400,9 @@ void ServiceWorkerVersion::OnPostMessageToClient(
return; return;
} }
if (provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) { if (provider_host->document_url().GetOrigin() != script_url_.GetOrigin()) {
// The client does not belong to the same origin as this ServiceWorker, mojo::ReportBadMessage(
// possibly due to timing issue or bad message. "Received Client#postMessage() request for a cross-origin client.");
binding_.Close();
return; return;
} }
provider_host->PostMessageToClient(this, std::move(message->data)); provider_host->PostMessageToClient(this, std::move(message->data));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment