|
| 1 | +# MSC4174: Web Push pusher kind |
| 2 | + |
| 3 | +As stated in MSC3013: |
| 4 | + |
| 5 | +Push notifications have the problem that they typically go through third-party gateways in order to |
| 6 | +be delivered, e.g. FCM (Google) or APNs (Apple) and an app-specific gateway (sygnal). In order to |
| 7 | +prevent these push gateways from being able to read any sensitive information the `event_id_only` format |
| 8 | +was introduced, which only pushes the `event_id` and `room_id` of an event down the push. After |
| 9 | +receiving the push message the client can hit the `GET /_matrix/client/r0/rooms/{roomId}/event/{eventId}` |
| 10 | +to fetch the full event, and then create the notification based on that. |
| 11 | + |
| 12 | +Even the `event_id_only` leaks some metadata that can be avoided. |
| 13 | + |
| 14 | +Today, web clients (eg. hydrogen, probably element web/desktop), needs to use a matrix to webpush gateway. |
| 15 | +This requires goind over the specifications, because they use `endpoint`, and `auth` in the `PusherData` |
| 16 | +(hydrogen [1], sygnal [2]), while the specifications let understand that only `url` and `format` are allowed [3]. |
| 17 | +=> __PusherData already need to be updated__ to add `auth` and `endpoint`. |
| 18 | + |
| 19 | +Web Push is a standard for (E2EE) push notifications, defined with RFC8030+RFC8291+RFC8292: many libraries |
| 20 | +are already available and robuste: they are reviewed, and acknowledge by experts. |
| 21 | + |
| 22 | +Having a webpush push kind would provide push notifications without gateway to |
| 23 | +- Web app and desktop app |
| 24 | +- Android apps using UnifiedPush (MSC2970 was open for this and won't be required anymore) |
| 25 | +- Maybe other ? We have seen apple moving a lot into web push support |
| 26 | + |
| 27 | +[1] https://github.com/element-hq/hydrogen-web/blob/9b68f30aad329c003ead70ff43f289e293efb8e0/src/platform/web/dom/NotificationService.js#L32 |
| 28 | +[2] https://github.com/matrix-org/sygnal/blob/main/sygnal/webpushpushkin.py#L152 |
| 29 | +[3] https://spec.matrix.org/v1.9/client-server-api/#post_matrixclientv3pushersset (search for PusherData) |
| 30 | + |
| 31 | +## Proposal |
| 32 | + |
| 33 | +`PusherData` fields are now define as follow: |
| 34 | +- `format`: Required if `kind` is `http` or `webpush`, not used if `kind` is `email`. The format to send |
| 35 | +notifications in to Push Gateways. The details about what fields the homeserver should send to the push gateway |
| 36 | +are defined in the Push Gateway Specification. Currently the only format available is ’event_id_only'. |
| 37 | +- `url`: Required if `kind` is `http`, not used else. The URL to use to send notifications to. MUST be an |
| 38 | +HTTPS URL with a path of /_matrix/push/v1/notify |
| 39 | +- `endpoint`: Required if `kind` is `webpush`, not used else. The URL to send notification to, as defined as a |
| 40 | +`push resource` by RFC8030. MUST be an HTTPS URL. |
| 41 | +- `auth`: Required if `kind` is `webpush`, not used else. The authentication secret. This is 16 random bytes |
| 42 | +encoded in base64 url. |
| 43 | + |
| 44 | +The POST request to the endpoint dedicated to the creation, modification and deletin of pushers, |
| 45 | +`POST /_matrix/client/v3/pushers/set` now supports a new `kind`: `webpush`. |
| 46 | +- `kind`: Required: The `kind` of pusher to configure. `http` makes a pusher that sends HTTP pokes. `webpush` makes a |
| 47 | +pusher that sends Web Push encrypted messages. `email` makes a pusher that emails the user with unread notifications. |
| 48 | +`null` deletes the pusher. |
| 49 | +- `pushkey`: Required: This is a unique identifier for this pusher. The value you should use for this is the routing |
| 50 | +or destination address information for the notification, for example, the APNS token for APNS or the Registration ID |
| 51 | +for GCM. If your notification client has no such concept, use any unique identifier. Max length, 512 bytes. |
| 52 | +If the `kind` is "email", this is the email address to send notifications to. |
| 53 | +If the `kind` is `webpush`, this is the user agent public key encoded in base64 url. The public key comes from a ECDH |
| 54 | +keypair using the P-256 (prime256v1, cf. FIPS186) curve. |
| 55 | + |
| 56 | +## Potential issues |
| 57 | + |
| 58 | +While implemnting, one have to be carreful with RFC8291: many libraries use the 4th draft of this spec. Checking the |
| 59 | +Content-Encoding header is a good way to know if it the correct version. If the value is `aes128gcm`, then it uses |
| 60 | +the right specifications, else (`aesgcm`), then it uses the draft version. |
| 61 | + |
| 62 | +## Alternatives |
| 63 | + |
| 64 | +`pushkey` could be a random ID, and we can add `p256dh` in the `PusherData`. But it would require client to store it, |
| 65 | +while the public key already identify that pusher. And, client already use the PusherData that way. |
| 66 | + |
| 67 | +## Security considerations |
| 68 | + |
| 69 | +Security considerations are listed by RFC8030 [4], there are mainly resolved with RFC8291 (Encryption) and |
| 70 | +RFC8292 (VAPID). |
| 71 | + |
| 72 | +Like any other federation request, there is a risk of SSRF. This risk is limited since the post data isn't |
| 73 | +arbitrary (the content is encrypted), and a potential malicious actor don't have access to the response. |
| 74 | +Nevertheless, it is recommended to not post to private addresses, with the possibility with a setting to |
| 75 | +whitelist a private IP. (Synapse already have ip_range_whitelist [5]) |
| 76 | +It is also recommended to not follow redirection, to avoid implementationissue where the destination is check |
| 77 | +before sending the request but not for redirections. |
| 78 | + |
| 79 | +Like any other federation request, there is a risk of DOS amplification. One malicious actor register many users |
| 80 | +to a valid endpoint, then change the DNS record and target another server, then notify all these users. This |
| 81 | +amplification is very limited since HTTPS is required and the TLS certificate of the target will be rejected. The |
| 82 | +request won't reach any functionnality of the targeted application. The home server can reject pusher if the response |
| 83 | +code is not one intended. |
| 84 | + |
| 85 | +[4] https://www.rfc-editor.org/rfc/rfc8030#section-8 |
| 86 | +[5] https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#ip_range_whitelist |
| 87 | + |
| 88 | +## Unstable prefix |
| 89 | + |
| 90 | +- |
| 91 | + |
| 92 | +## Dependencies |
| 93 | + |
| 94 | +- |
| 95 | + |
0 commit comments