[2.x] fix(notifications): scope notification queries to the authenticated user#4441
Merged
Conversation
The Update endpoint for NotificationResource fetched notifications by ID using an unscoped query, allowing any authenticated user to retrieve the contents of any other user's notification by guessing its sequential ID. The Index (listing) endpoint was correctly scoped via NotificationRepository, but this scope was not applied to the Update path, which falls through to AbstractDatabaseResource::find() — an unscoped Eloquent query. Fix by overriding scope() in NotificationResource to unconditionally filter all queries by the actor's user_id. This ensures any lookup — not just the inbox listing — returns 404 for notifications belonging to other users. The write side (marking a notification as read) was separately protected by an ownership check in ReadNotificationHandler, so no data was ever modified across ownership boundaries. The exposure was read-only. Reported by Lakshmikanthan K (github.com/l3tchupkt) via responsible disclosure. Thanks for the thorough and well-written report. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
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.
Summary
Fixes an IDOR vulnerability in
NotificationResourcewhere theUpdateendpoint fetched notifications by ID using an unscoped query, allowing any authenticated user to read the contents of any other user's notification by guessing its sequential ID.Index(listing) endpoint was correctly scoped viaNotificationRepository— this is not affectedUpdatepath falls through toAbstractDatabaseResource::find(), which uses an unscoped Eloquent query — this is the affected pathReadNotificationHandler; the exposure was read-onlyFix: override
scope()inNotificationResourceto filter all queries byuser_id = actor->id, ensuring any lookup returns 404 for notifications belonging to other users.Introduced in: #3971 (the JSON:API rewrite). This did not exist in 1.x — the old
UpdateNotificationControllerexclusively dispatchedReadNotificationHandler, which always enforced ownership. The new architecture separates the fetch from the action, and the fetch was left unscoped.Tests
Five tests added/extended across
UpdateTestandListTest:user_cannot_read_another_users_notification— core IDOR: empty PATCH by another user returns 404user_cannot_mark_another_users_notification_as_read— PATCH withisRead: truereturns 404 and leavesread_atunchangedadmin_cannot_read_another_users_notification— admins are equally scoped; notifications are personallisting_only_returns_own_notifications— confirms the listing endpoint is not affectedguest_cannot_update_notification— unauthenticated requests are rejectedThe two IDOR tests fail against the unfixed code (returning 200) and pass after the fix.
Credit
Reported by Lakshmikanthan K (@l3tchupkt) via responsible disclosure. Thanks for the thorough and accurate report.
Changelog
Fixed: Authenticated users could read notification contents belonging to other users via the
PATCH /api/notifications/{id}endpoint (IDOR). Reported by Lakshmikanthan K.