Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1342)

Unified Diff: content/browser/push_messaging/push_messaging_message_filter.cc

Issue 1931843002: Ship Web Push subscription restrictions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/push_messaging/push_messaging_message_filter.cc
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc
index 107b06f337a52e97d5832841472045dc1bd46ddf..4417ed872aa699531fbeae22d4c9de602feaf080 100644
--- a/content/browser/push_messaging/push_messaging_message_filter.cc
+++ b/content/browser/push_messaging/push_messaging_message_filter.cc
@@ -80,11 +80,10 @@ void ForwardEncryptionInfoToIOThreadProxy(
base::Bind(callback, success, p256dh, auth));
}
-// Concatenates the subscription id with the endpoint base to create a new
-// GURL object containing the endpoint unique to the subscription.
-GURL CreatePushEndpoint(const GURL& push_endpoint_base,
- const std::string& push_subscription_id) {
- return GURL(push_endpoint_base.spec() + "/" + push_subscription_id);
+// Returns whether |sender_info| contains a valid application server key, that
+// is, a NIST P-256 public key in uncompressed format.
+bool IsApplicationServerKey(const std::string& sender_info) {
+ return sender_info.size() == 65 && sender_info[0] == 0x04;
}
} // namespace
@@ -97,6 +96,7 @@ struct PushMessagingMessageFilter::RegisterData {
GURL requesting_origin;
int64_t service_worker_registration_id;
bool user_visible;
+ bool uses_standard_protocol;
// The following member should only be read if FromDocument() is true.
int render_frame_id;
};
@@ -185,6 +185,7 @@ PushMessagingMessageFilter::RegisterData::RegisterData()
: request_id(0),
service_worker_registration_id(0),
user_visible(false),
+ uses_standard_protocol(false),
render_frame_id(ChildProcessHost::kInvalidUniqueID) {}
bool PushMessagingMessageFilter::RegisterData::FromDocument() const {
@@ -218,9 +219,15 @@ PushMessagingMessageFilter::PushMessagingMessageFilter(
// constructor finishes.
ui_core_.reset(
new Core(weak_factory_io_to_io_.GetWeakPtr(), render_process_id));
- PushMessagingService* push_service = ui_core_->service();
- if (push_service)
- push_endpoint_base_ = push_service->GetPushEndpoint();
+
+ PushMessagingService* service = ui_core_->service();
+ service_available_ = !!service;
+
+ if (service_available_) {
+ default_endpoint_ = service->GetEndpoint(false /* standard_protocol */);
+ web_push_protocol_endpoint_ =
+ service->GetEndpoint(true /* standard_protocol */);
+ }
}
PushMessagingMessageFilter::~PushMessagingMessageFilter() {}
@@ -262,6 +269,7 @@ void PushMessagingMessageFilter::OnSubscribeFromDocument(
data.service_worker_registration_id = service_worker_registration_id;
data.render_frame_id = render_frame_id;
data.user_visible = options.user_visible_only;
+ data.uses_standard_protocol = IsApplicationServerKey(options.sender_info);
ServiceWorkerRegistration* service_worker_registration =
service_worker_context_->GetLiveRegistration(
@@ -289,6 +297,7 @@ void PushMessagingMessageFilter::OnSubscribeFromWorker(
data.request_id = request_id;
data.service_worker_registration_id = service_worker_registration_id;
data.user_visible = options.user_visible_only;
+ data.uses_standard_protocol = IsApplicationServerKey(options.sender_info);
ServiceWorkerRegistration* service_worker_registration =
service_worker_context_->GetLiveRegistration(
@@ -551,23 +560,23 @@ void PushMessagingMessageFilter::SendSubscriptionSuccess(
const std::vector<uint8_t>& auth) {
// Only called from IO thread, but would be safe to call from UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (push_endpoint_base_.is_empty()) {
+ if (!service_available_) {
// This shouldn't be possible in incognito mode, since we've already checked
// that we have an existing registration. Hence it's ok to throw an error.
DCHECK(!ui_core_->is_incognito());
SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE);
return;
}
+
+ const GURL endpoint =
+ CreateEndpoint(data.uses_standard_protocol, push_subscription_id);
+
if (data.FromDocument()) {
Send(new PushMessagingMsg_SubscribeFromDocumentSuccess(
- data.render_frame_id, data.request_id,
- CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
- auth));
+ data.render_frame_id, data.request_id, endpoint, p256dh, auth));
} else {
Send(new PushMessagingMsg_SubscribeFromWorkerSuccess(
- data.request_id,
- CreatePushEndpoint(push_endpoint_base_, push_subscription_id), p256dh,
- auth));
+ data.request_id, endpoint, p256dh, auth));
}
RecordRegistrationStatus(status);
}
@@ -788,15 +797,37 @@ void PushMessagingMessageFilter::OnGetSubscription(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(johnme): Validate arguments?
service_worker_context_->GetRegistrationUserData(
+ service_worker_registration_id, kPushSenderIdServiceWorkerKey,
+ base::Bind(&PushMessagingMessageFilter::DidGetSenderInfo,
+ weak_factory_io_to_io_.GetWeakPtr(), request_id,
+ service_worker_registration_id));
+}
+
+void PushMessagingMessageFilter::DidGetSenderInfo(
+ int request_id,
+ int64_t service_worker_registration_id,
+ const std::string& sender_info,
+ ServiceWorkerStatusCode status) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (status != SERVICE_WORKER_OK) {
+ DidGetSubscription(request_id, service_worker_registration_id,
+ false /* uses_standard_protocol */,
+ std::string() /* push_subscription_id */, status);
+ return;
+ }
+
+ const bool uses_standard_protocol = IsApplicationServerKey(sender_info);
+ service_worker_context_->GetRegistrationUserData(
service_worker_registration_id, kPushRegistrationIdServiceWorkerKey,
base::Bind(&PushMessagingMessageFilter::DidGetSubscription,
weak_factory_io_to_io_.GetWeakPtr(), request_id,
- service_worker_registration_id));
+ service_worker_registration_id, uses_standard_protocol));
}
void PushMessagingMessageFilter::DidGetSubscription(
int request_id,
int64_t service_worker_registration_id,
+ bool uses_standard_protocol,
const std::string& push_subscription_id,
ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -804,7 +835,7 @@ void PushMessagingMessageFilter::DidGetSubscription(
PUSH_GETREGISTRATION_STATUS_STORAGE_ERROR;
switch (service_worker_status) {
case SERVICE_WORKER_OK: {
- if (push_endpoint_base_.is_empty()) {
+ if (!service_available_) {
// Return not found in incognito mode, so websites can't detect it.
get_status =
ui_core_->is_incognito()
@@ -819,7 +850,7 @@ void PushMessagingMessageFilter::DidGetSubscription(
const GURL origin = registration->pattern().GetOrigin();
const GURL endpoint =
- CreatePushEndpoint(push_endpoint_base_, push_subscription_id);
+ CreateEndpoint(uses_standard_protocol, push_subscription_id);
auto callback =
base::Bind(&PushMessagingMessageFilter::DidGetSubscriptionKeys,
@@ -977,6 +1008,15 @@ void PushMessagingMessageFilter::SendIPC(
Send(message.release());
}
+GURL PushMessagingMessageFilter::CreateEndpoint(
+ bool standard_protocol,
+ const std::string& subscription_id) const {
+ const GURL& base =
+ standard_protocol ? web_push_protocol_endpoint_ : default_endpoint_;
+
+ return GURL(base.spec() + subscription_id);
+}
+
PushMessagingService* PushMessagingMessageFilter::Core::service() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* process_host =

Powered by Google App Engine
This is Rietveld 408576698