[00.00_r1gor]
[00.00_bugbounty]
r1gor

all write-ups

Missing Auth Check to Self-Replicating Worm

Target is a collaborative writing platform with AI features, TTS narration, real-time editing. Think Google Docs but smaller.

The core bug was architectural. The server gave every authenticated user implicit viewer access to every document. Then it relied on per-endpoint role checks that were inconsistently applied. Some endpoints checked. Some did not. Some crashed.

the evidence

# hard denial (correct):
GET  /api/doc/VICTIM -> "Access denied"

# soft denial (broken):
POST /api/doc/VICTIM/updates/client -> "Insufficient permissions.
     Editor or manager access required."

"Editor or manager access required" means the server recognized me as a viewer on someone else's doc. The auth model defaults to yes and needs explicit no. Backwards.

narration endpoint: no check at all

curl -X POST "https://[TARGET]/api/doc/VICTIM_DOC/narrate" \
  -H "Cookie: auth_token=ATTACKER" \
  -d '{"text":"draining your quota"}'
# Returns audio. Works on any document.

Confirmed on 5 documents. Doc serials are sequential so you enumerate and drain every user's paid TTS quota.

AI endpoints: crash the whole service

POST /api/doc/VICTIM/ai/edit  -> 502
POST /api/doc/VICTIM/ai/chat  -> 503

No auth check, but the server crashes processing unauthorized doc data. Hitting about 10 doc serials caused full 503 for 30 seconds across the entire platform. Unauthenticated DoS via enumeration.

The scary part. The ai/edit endpoint loaded the victim's document from Postgres with zero authorization. It only failed because a BigInt clock value overflowed int32. If someone fixes that type bug without adding auth, the endpoint becomes full document read via AI summarization.

stored XSS in chat

The chat panel rendered raw HTML. No sanitization, no CSP enforcement (script-src had unsafe-inline).

<img src=x onerror="fetch('/api/doc/VICTIM/access/collaborator/manager',
  {method:'POST',headers:{'Content-Type':'application/json'},
  body:JSON.stringify({email:'attacker@gmail.com'})})">

five attack chains

Chain 1: one-click platform breach. Open redirect in OAuth flow sends victim to attacker's public doc. Stored XSS steals auth_token. Admin token gives access to every document, every AI request (with user emails, prompts, outputs), full version history.

Chain 2: quota theft at scale. Enumerate sequential doc serials. Hit /narrate on each. Drain TTS quota across the user base.

Chain 3: cascading DoS. Enumerate serials. Rapid requests to /narrate and /ai/edit. Full 503 for all users, confirmed.

Chain 4: XSS to manager on any doc. Attacker creates public doc with XSS payload. Open redirect lures doc owner to it. XSS fires in owner's browser, calls /access/collaborator/manager to add attacker. Attacker now has full read/write/delete on victim's doc.

Chain 5: wormable infection. Steal victim's token via XSS. Use stolen token to inject XSS into victim's shared docs. Each shared doc infects its viewers. Exponential spread across the collaboration network.

root cause

No centralized auth middleware. Each endpoint implements its own check (or does not). The implicit viewer grant means any new endpoint without an explicit deny is automatically vulnerable. The XSS is just unsanitized HTML rendering in the chat.

Everything here is basic stuff. Centralized auth middleware, HTML sanitization, CSP without unsafe-inline, OAuth redirect validation. The bugs are not exotic. The chains they enable are.