OpenAI Assistants API: Thread-ID Enumeration and Hijacking

Thread IDs in the Assistants API are long but predictable in vibe-coded chat UIs. A classic IDOR lets attackers read prior conversations by incrementing a counter on your side.
OpenAI's Assistants API gives each conversation a thread_id that starts with thread_ + a random suffix. If you use it directly from the browser, it's safe — the suffix is 48 random bytes.
But vibe-coded apps rarely use it directly. They proxy through their own API and often map thread IDs to an incrementing integer on the DB side for "cleaner URLs":
/chat/12 → thread_abcd1234
/chat/13 → thread_efgh5678
Now an attacker browses /chat/1, /chat/2, /chat/3 — and reads everyone's conversations with your assistant.
Fix
- Don't expose internal thread IDs in URLs. If you must, enforce ownership on every fetch:
const thread = await db.thread.findFirst({ where: { id: args.id, userId: ctx.user.id }, }); - Delete threads aggressively. OpenAI charges per-token on every re-read; the permanent storage is their cost, not your value.
- Sign thread URLs with a short-lived JWT if users share them.
VibeWShield detection
The auth_check scanner looks for endpoints where incrementing a numeric segment changes the response body. A chat URL that returns someone else's messages is flagged as high-severity IDOR.
Free security scan
Test your app for these vulnerabilities
VibeWShield automatically scans for everything covered in this article and more — 18 security checks in under 3 minutes.
Scan your app free