New issue
Advanced search Search tips

Issue 596121 link

Starred by 4 users

Issue metadata

Status: WontFix
Owner: ----
Closed: Mar 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Feature



Sign in to add a comment

Improve web push error messages

Project Member Reported by stillers@google.com, Mar 18 2016

Issue description

If invalid push notification parameters are provided, then in some cases, GCM and/or Chrome silently drop messages. It would be helpful if suitable error messages could be displayed to the developer instead.

The following curl command successfully delivers a push message (with body) to 51.0.2680.0 canary (OS X, 64-bit):

echo -ne '\xe3\x2d\xf1\xce\xb5\xe0\x87\x10\x57\x4d\xb9\xe1\xc7\xa6\xce\xa9\x12\x92\x54\x03\x1f\x6c\x6f\xc6\x17\xbb\xe5\x90\xa4\xc2' | curl -v -H 'Encryption: salt=3RayP4jYNOQSaF1Q7lJk7A' -H 'Crypto-Key: dh=BJyKJuql1kkDV57HR_iTi2RfOOsUjJvVojVbi9KFxFLpVzA94Yk8HJSGo__przqe8MXbPDN-BXLg8BlD1_Ta224' -H 'Authorization: key=AIzaSyCCnwbi86n7YAY5PXF-D9odfmEHfr0OvYI' 'https://gcm-http.googleapis.com/gcm/cbTsrJQ5ggs:APA91bFxAR8rFaxdWAgfop9dxqVCnBfZbe63dDP6F9NicBC4tvHPhkriAw-h_RqzCJonjZNVOdxi3diLkvfTZDp6luP5IJC4Y2QHwdDVaGZvoLvmPmajX2KWp6WY-vACLU3enPmhGqn7' --data-binary @-

There are at least five parameters that could be corrupted:

- the message body
- the salt attribute of encryption header
- the dh attribute crypto-key header
- the key attribute authorization header
- the URL endpoint

In each case, developers may expect that in the event of corruption, an error would be issued, either by the server or the client. However this is not always the case.

- the message body - 201 Created from server, message not received by client (SILENTLY DROPPED)
- the salt attribute of encryption header - 201 Created from server, message not received by client (SILENTLY DROPPED)
- the dh attribute crypto-key header - 201 Created from server, message not received by client (SILENTLY DROPPED)
- the key attribute authorization header - 400 UnauthorizedRegistration from server (ERROR AS EXPECTED)
- the URL endpoint - 400 InvalidRegistration from server (ERROR AS EXPECTED)
 

Comment 1 by peter@chromium.org, Mar 18 2016

This mostly is lacking documentation— we expose five additional errors on chrome://gcm-internals on all platforms:

  - "Invalid format for the Encryption header" (i.e. the salt or record size)
  - "Invalid format for the Crypto-Key header" (i.e. the `dh` value)
  - "AES-GCM decryption failed" (i.e. the payload)

... and two internal ones that you shouldn't run in to:

  - "There are no associated keys with the subscription"
  - "The shared secret cannot be derived from the keying material"

We don't show them in DevTools because it's fairly unlikely that a service worker for the origin is running whilst this happens, and starting a service worker for the odd chance that the developer is looking at it is expensive. (Additionally, layering makes this interesting.)

The other two you mention, endpoint or authentication errors, are server-sided errors for messages that won't even reach Chrome. There's nothing we can really do there.

Having a mechanism for validating the messages sent to users is important, for which I created the push verifier:

https://tests.peter.sh/push-encryption-verifier/

Does this answer your request?

Comment 2 by benl...@mobify.me, Mar 18 2016

This is less a developer problem (for us) than it is a production issue. If we send messages out to the (tens of thousands) of subscribers, and any of the above parameters are corrupted, then our server has no way to detect that. The clients are running on end-user devices, not developer setups, so any errors exposed in Chrome aren't visible either.

Comment 3 by peter@chromium.org, Mar 18 2016

Why would any of these values end up being corrupted?

Using chrome://gcm-internals/ does not require any special configuration.

We don't have an answer for that case today, but are looking in to changing the acknowledgements to only be fired when the Service Worker has handled the message. That's quite far in the future, however, and won't give you any kind of detailed data.

Comment 4 by benl...@mobify.me, Mar 18 2016

Corruption's possible because bugs :) Suppose there's a defect in how our worker/client encodes the key for sending to our server, but this only affects keys with certain bytes in. We accept and store the corrupted values, and our server sends messages to them, along with all the non-corrupted values. We see no errors (we send *tens of thousands of messages per day*) and yet some users never get a message, and we have no way to detect this.  We can't ask end-users to open up chrome://gcm-internals/ to debug stuff.

Comment 5 by peter@chromium.org, Mar 18 2016

I'm afraid that there's not much we can do to help you there.

Today, I would encourage you to write unit tests on random keying data to capture such issues in the client-side logic. At a slightly higher level, we do encourage people to simply call JSON.stringify() on the PushSubscription object to avoid this sort of issue altogether:

navigator.serviceWorker.ready.then(registration => {
    registration.pushManager.subscribe().then(subscription => {
        const serializedSubscription = JSON.stringify(subscription);
        // send |serializedSubscription| to the server.
    });
});

A second thing you could consider, assuming you run some sort of analytics, is measure the ratio of messages send by your server against messages received by the client, and tracking significant differences in these numbers.

Then, in the longer future, once we support delivery receipts in our Web Push protocol it will most likely be based on acknowledgement of the Service Worker handling the message, rather than the device having received *a* message regardless of whether it can be handled or not.

Comment 6 by peter@chromium.org, Mar 21 2016

Status: WontFix (was: Untriaged)
Let me close this issue per #5.

Please let Michael or myself know if there's anything else, sorry that this isn't more actionable!

Sign in to add a comment