Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍 PyPI
Not in CISA KEV

CVE-2026-44504 — aegra-api

Fix: aegra/aegra#337

CVE-2026-44504 is a CWE-285 vulnerability in aegra-api. A fix is available for aegra-api — see the affected versions and patch details below.

Aegra: Cross-user run injection in /threads/{thread_id}/runs (IDOR)

Also known asGHSA-m98r-6667-4wq7PYSEC-2026-2328
Published
May 14, 2026
Updated
Aug 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 21, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-44504.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs21th percentile — riskier than 21% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Real-World Exposure

1 pkg affected
🐍aegra-api

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

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:

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

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIaegra-api≥ 0.9.0&&< 0.9.70.9.7pip install --upgrade 'aegra-api==0.9.7'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for aegra-api, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update aegra-api to 0.9.7 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-44504 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-44504 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2026-44504. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## 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
O3 Security · Impact-Aware SCA

Is CVE-2026-44504 in your dependencies?

O3 Security finds CVE-2026-44504 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2026-44504: aegra-api | O3 Security