Skip to content

Back to the catalog

Predicting MongoDB ObjectId continuously in Rocket.Chat
aikido.devwriteup

Predicting MongoDB ObjectId continuously in Rocket.Chat

Aikido researchers detail an unauthenticated IDOR in Rocket.Chat's file-upload access control (Livechat room ID vs. file's actual room ID were never compared), letting an anonymous visitor read any uploaded file if the MongoDB ObjectId() file ID is known. They then show ObjectId()s are highly predictable (4-byte timestamp + static 5-byte machine value + incrementing 3-byte counter), and build an async Python tool that continuously probes an anchor ID and brute-forces the narrow timestamp/counter gaps to leak every file uploaded to a live instance in near real time. Reported April 21 via HackerOne, fixed in Rocket.Chat 8.5.1/8.4.4/8.3.6/8.2.6/8.1.6/8.0.7/7.13.9/7.10.13; the authors recommend UUIDv4 over ObjectId() for any secret-facing identifier.

TL;DR Rocket.Chat IDOR + predictable MongoDB ObjectId()s let attackers continuously enumerate and leak every uploaded file on an instance; fixed, with full exploit code and mitigation guidance (use UUIDv4, not ObjectId()).
Document

What it is

A pre-auth arbitrary file read in Rocket.Chat's Livechat file-upload authorization, chained with MongoDB ObjectId predictability to enumerate every uploaded file. Reported to HackerOne (#3687142) on 21 April, disclosed and fixed by 12 June in 8.5.1, 8.4.4, 8.3.6, 8.2.6, 8.1.6, 8.0.7, 7.13.9, and 7.10.13. Found by Aikido's AI pentest agents.

How it works

Files from both authenticated channels and unauthenticated Livechat are stored at the same path, /file-upload/{fileId}. Authorization has two independent notions of Room ID that are never reconciled:

  • requestCanAccessFiles in FileUpload.ts reads rc_rid from the query string and checks it against rc_token via LivechatRooms.findOneByIdAndVisitorToken(rid, token) — i.e. "do you hold a valid session for this room."
  • Separately, the file is fetched by path with Uploads.findOneById(match[1]). That file carries its own rid, which may differ from the query-string rc_rid.

Nothing checks that the requested file's real rid matches the room you authorized against. So an attacker registers a throwaway Livechat visitor, obtains a valid dummy Room ID, then supplies any file's ObjectId in the path — bypassing the 403 a private file returns to an unauthenticated browser. Because MongoDB ObjectId()s embed a timestamp and are not cryptographically random, probing the current ID lets an attacker predict and enumerate all others, harvesting files continuously.

Exploit primitives (verbatim from the page):

HOST = "https://rocketchat.local"
FILE_ID = "6a325394876fbe9c70b1b03f"
s = requests.Session()
token = "x"
# Create anonymous visitor with token
s.post(f"{HOST}/api/v1/livechat/visitor",
       json={"visitor": {"token": token, "name": "attacker", "email": "attacker@example.com"}})
# Get our Room ID
r = s.get(f"{HOST}/api/v1/livechat/room",
          params={"token": token, "agentId": "rocket.cat"})

Preconditions / Affected

Unauthenticated — anyone with network access. The key exposure detail the summary omits: Livechat is enabled by default, and even though its file-upload input is disabled by default (invisible in the widget), the upload API endpoint remains reachable. Reach it directly at /livechat. Default installs where self-registration is off are still vulnerable.

What to do

Upgrade to one of the fixed versions listed above or newer. Since the exploit is unauthenticated, treat internet-exposed instances as urgent. As a stopgap, consider disabling Livechat if unused.

Caveats

The published exploit script is truncated before the ObjectId-prediction loop, so the exact enumeration cadence isn't shown in this excerpt. The authors note the technique generalizes to other MongoDB apps sharing these primitives, not just Rocket.Chat.

Organisations named here

  • HackerOne #3687142

Technologies named here

  • Rocket.Chat
  • Aikido AI Pentest
  • MongoDB
  • HackerOne
  • Python requests library
  • httpx
  • tqdm
  • asyncio
  • Python
  • Aikido Security

Techniques named here

  • Unauthenticated Livechat abuse as attack primitive
  • MongoDB ObjectId prediction / anchor-point attack
  • Continuous probing with sliding window / gap detection
  • Asynchronous concurrent brute forcing
  • Counter wraparound handling
  • IDOR