## Impact Aegra deployments running 0.9.0 through 0.9.6 with multiple authenticated users on a shared instance are vulnerable to a cross-tenant IDOR. Any authenticated user (User A), given another user's `thread_id` (User B), can: - Execute graph runs against User B's thread via `POST...
Full CISO analysis pending enrichment.
Affected Systems
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| aegra-api | pip | >= 0.9.0, < 0.9.7 | 0.9.7 |
Do you use aegra-api? You're affected.
Severity & Risk
Recommended Action
Patch available
Update aegra-api to version 0.9.7
Compliance Impact
Compliance analysis pending. Sign in for full compliance mapping when available.
Frequently Asked Questions
What is CVE-2026-44504?
Aegra has cross-user run injection in /threads/{thread_id}/runs (IDOR)
Is CVE-2026-44504 actively exploited?
No confirmed active exploitation of CVE-2026-44504 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-44504?
Update to patched version: aegra-api 0.9.7.
What is the CVSS score for CVE-2026-44504?
No CVSS score has been assigned yet.
Technical Details
NVD Description
## Impact Aegra deployments running 0.9.0 through 0.9.6 with multiple authenticated users on a shared instance are vulnerable to a cross-tenant IDOR. Any authenticated user (User A), given another user's `thread_id` (User B), can: - Execute graph runs against User B's thread via `POST /threads/{thread_id}/runs`, `POST /threads/{thread_id}/runs/stream`, or `POST /threads/{thread_id}/runs/wait` - Read User B's full checkpoint state via the resulting run's `output` field - Inject arbitrary messages into User B's conversation history (persisted in B's checkpoint) - Hide their activity from User B's `GET /threads/{thread_id}/runs` listing because the run carries A's `user_id` The streaming variant is worse — the first SSE `event: values` frame returns the entire prior `messages` array immediately on connection, no graph execution needed. Thread IDs are UUIDs but leak through frontend URLs, server logs, observability traces, and shared links. Guessing is not required. ## Patches Fixed in **0.9.7**. The three affected endpoints now perform an SQL-level `user_id == authenticated_user.identity` check before calling `_prepare_run`. When the thread exists but is owned by another user, the response is `404 Thread not found` (matching the read-side pattern) to avoid leaking thread existence. ## Workarounds If upgrade is not immediately possible, register an `@auth.on("threads", "create_run")` handler that explicitly verifies thread ownership against the authenticated identity before allowing the operation. Without a handler, no built-in authorization runs on these write paths. Example mitigation handler: ```python from langgraph_sdk import Auth auth = Auth() @auth.on("threads", "create_run") async def enforce_thread_owner(ctx: Auth.types.AuthContext, value: dict): # Look up the thread, raise 404 if not owned by ctx.user.identity. # Implementation depends on your data layer. ... ``` ## Root cause Aegra's authorization model delegates per-resource policy to user-defined `@auth.on` handlers. When no handler is registered, `handle_event(...)` returns `None` and the request proceeds (default-allow). Read endpoints in `api/threads.py` add a defense-in-depth `user_id` filter at the SQL layer, but the run-creation endpoints in `api/runs.py` skipped that filter. Result: out-of-the-box deployments without custom auth handlers were vulnerable. ## Affected endpoints - `POST /threads/{thread_id}/runs` - `POST /threads/{thread_id}/runs/stream` - `POST /threads/{thread_id}/runs/wait` Stateless variants (`POST /runs`, `POST /runs/wait`, `POST /runs/stream`) are NOT affected — they generate a fresh `thread_id` server-side and never accept a caller-supplied one. ## Credits - @JoJoTheBizarre — discovered and reported the vulnerability with a precise reproducer (#336) - @victorjmarin and @jawhardjebbi — wrote the fix and added test coverage at unit, integration, and manual-auth e2e levels (#337) ## Resources - Issue: https://github.com/aegra/aegra/issues/336 - Fix PR: https://github.com/aegra/aegra/pull/337 - Release: https://github.com/aegra/aegra/releases/tag/v0.9.7
Weaknesses (CWE)
References
Timeline
Related Vulnerabilities
CVE-2025-8709 7.3 langgraph-checkpoint-sqlite: SQL Injection exposes database
Same package: langgraph CVE-2025-67644 7.3 langgraph-checkpoint-sqlite: SQL Injection exposes database
Same package: langgraph CVE-2025-64104 7.3 langgraph-checkpoint-sqlite: SQL Injection exposes database
Same package: langgraph CVE-2026-28277 6.8 langgraph: Deserialization enables RCE
Same package: langgraph CVE-2026-27794 6.6 langgraph-checkpoint: Deserialization enables RCE
Same package: langgraph
AI Threat Alert