Closed floatingstone closed 7 years ago
Hi @floatingstone, thank you for the questions! Please do note that there is a repository for VAPID (https://github.com/webpush-wg/webpush-vapid) as well, but it's relevant enough so I'll answer your questions in this issue.
- Should all of the subscribe requests's applicationServerKey be stored in the push service database?
The application server definitely has to remember which key was used, if it has several, as it will need to proof possession of the associated private key by signing the JWT token.
The push service needs to store this key if it decides to support Subscription Restrictions (see section 4). Otherwise the k
parameter in the Authorization
header will do.
Note that, to my knowledge, all public push services that support VAPID also support Subscription Restrictions.
- VAPID replay attacks.
Indeed: this is detailed in section 5. Using near-immediate, say a couple of seconds if your server accurately keeps time, expiration times is the best way to counter this.
- When application server wants to push encrypted messages: a) Does the push service need to check whether the request body has been replaced or not? b) Or just pass the encrypted messages to target subscriber?
The push service doesn't have the ability to decrypt the message, so the intention is for it to pass on the entire payload, unmodified, to the client.
@beverloo, Thank you so much for your reply, :)
The push service needs to store this key if it decides to support Subscription Restrictions (see section 4). Otherwise the k parameter in the Authorization header will do.
Should push service check the validation of this key before decide to store it ? If don't, following code may let the push service store a lot of useless information.
while (true) {
const newRandomStr = <random string...>;
const subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
newRandomStr
)
};
registration.pushManager.subscribe(subscribeOptions);
}
A push service can validate the keys, but that is up to them.
The Push API does say that applicationServerKey
has to be a valid P-256 point, so the while the user agent may do some verification, the push service may not. We (Google w/ Firebase Cloud Messaging) do validate.
I think that Firefox validates the point. The push service basically has to if it is verifying a signature.
(In other words, I was originally wrong.)
What about the following scenario? How does the push service store the applicationServerKey?
while(true) {
// construct a subscribe request using a fake "vapid" (changes every time);
// send the request to the push service;
}
Request format:
POST /subscribe/ HTTP/1.1 Host: push.example.net Content-Type: application/webpush-options+json;charset=utf-8 Content-Length:
{ "vapid": ".......fake infomation......." }
When talking in context of the Push API, because a Service Worker can only have a single subscription that'd have to be a subscribe-then-unsubscribe loop.
In either scenario, yes, that would create any number of subscriptions with different applicationServerKey
values. It's not defined how the push service stores this, but conceptually it's just a piece of metadata it stores with the subscription.
In either scenario, yes, that would create any number of subscriptions with different applicationServerKey values. It's not defined how the push service stores this, but conceptually it's just a piece of metadata it stores with the subscription.
This creates a lot of subscriptions that is not actually used. I think, for hackers, this could be a chance to attack the push service.
Yes, this is an operational risk of running a push service.
Let me close this - please reply or open a new issue if there's anything else! :)
1. Should all of the subscribe requests's applicationServerKey be stored in the push service database? When we subscribe a user, we pass in an applicationServerKey. This key is passed to the push service. Many forgery subscribe requests with different applicationServerKey can cause the push service to be attacked.
2. VAPID replay attacks. The authentication scheme of the VAPID is vulnerable to replay attacks if an attacker can acquire a valid JWT. So besides the "exp" value, what else can we do to reduce this risk?
3. When application server wants to push encrypted messages: a) Does the push service need to check whether the request body has been replaced or not? b) Or just pass the encrypted messages to target subscriber?