fix: validate subscription endpoint before persisting it - #89
Open
palmoni5 wants to merge 1 commit into
Open
Conversation
`Subscriptions.add` stored `subscription.endpoint` exactly as received. The endpoint is caller-supplied, and `plugin.onNotificationPush` later POSTs to it for every notification the user receives, so an authenticated user could register an arbitrary url and have the server request it repeatedly on their behalf. `POST /api/web-push/test` already runs `request.check()` before sending, but nothing guarded the write path, so the regular push path had no check at all. Reject the endpoint at `add()` unless it parses as a url, uses https, and passes `request.check()` (core's reserved-IP-range/DNS-rebinding guard). Also trim the endpoint on both add and remove so the sorted set member and the object key stay in sync with what the test route looks up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Subscriptions.addwritessubscription.endpointto the database exactly as it arrives fromPOST /api/web-push/subscription:Nothing validates it.
plugin.onNotificationPushthen hands the stored subscription straight towebPush.sendNotificationfor every notification the user receives, so an authenticated user can register an arbitrary url and get the server to POST to it repeatedly, at whatever rate they can generate notifications for themselves.POST /api/web-push/testalready runsrequest.check()before sending, but that only covers the explicit test button — the write path and the regular push path had no check at all, which is the inconsistency this fixes.web-pushrequiring https and validating certificates does limit what an attacker gets out of it in practice; plain-HTTP internal targets aren't reachable this way. It's still a stored, user-controlled request target that the server hits on a schedule the attacker influences.The fix validates at the single point where endpoints enter storage, so the push path needs no per-notification check:
https:request.check(), core's reserved-IP-range / DNS-rebinding guardadd()throws[[error:invalid-url]]and nothing is writtenIt also trims the endpoint on both
addandremove, so the sorted set member and theweb-push:subscriptions:<endpoint>key stay in sync with what the test route (which already trims) looks up.This only guards new writes — endpoints stored before this change are unaffected, and the
request.check()in the test route stays in place for them.