Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-56104

CVE-2026-56104: Chainlit Auth Bypass Vulnerability

CVE-2026-56104 is an authentication bypass flaw in Chainlit that enables session hijacking attacks. Unauthenticated attackers can restore valid sessions without ownership checks. This article covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-56104 Overview

Chainlit versions prior to 2.10.1 contain a session hijacking vulnerability in the WebSocket session restoration path. The flaw allows unauthenticated attackers to inherit authenticated user sessions by presenting a valid sessionId during reconnection, without any ownership verification. By exploiting the restore_existing_session function, an attacker assumes the victim's permissions and roles. This enables unauthorized invocation of tools and access to data restricted to the authenticated victim. The issue is classified under [CWE-862] Missing Authorization and has been patched in Chainlit release 2.10.1.

Critical Impact

Attackers who obtain or guess a valid session identifier can fully impersonate authenticated users, executing privileged tools and accessing sensitive data within the Chainlit application.

Affected Products

  • Chainlit versions prior to 2.10.1
  • Chainlit Python framework for conversational AI applications
  • Deployments exposing the Chainlit WebSocket session restoration endpoint

Discovery Timeline

  • 2026-06-22 - CVE-2026-56104 published to NVD
  • 2026-06-23 - Last updated in NVD database

Technical Details for CVE-2026-56104

Vulnerability Analysis

The vulnerability resides in Chainlit's WebSocket session handling logic within backend/chainlit/socket.py. When a client reconnects, the server calls restore_existing_session(sid, session_id, ...) to rebind the WebSocket to an existing WebsocketSession. The pre-patch implementation looked up the session by ID and restored it without checking whether the requesting client owned that session. Any actor presenting a valid sessionId could attach to that session and inherit the authenticated identity bound to it.

Once attached, the attacker operates with the victim's user context across the Chainlit runtime. This includes invoking server-side tools, sending messages on behalf of the user, and retrieving persisted thread data. In LLM-driven workflows where tools wrap sensitive APIs, this becomes a direct path to data exfiltration and privileged action execution.

Root Cause

The root cause is missing authorization [CWE-862] on the session restoration path. The server trusted the client-supplied session_id as sufficient proof of session ownership and did not compare the authenticated user against the user attached to the stored WebsocketSession.

Attack Vector

An attacker needs network reachability to the Chainlit WebSocket endpoint and a valid sessionId belonging to an authenticated user. Session identifiers can be obtained through log exposure, referrer leakage, shared environments, or other side channels. The attacker initiates a WebSocket connection and supplies the captured sessionId to trigger the restore_existing_session path.

python
     threadId: str | None
 
 
-def restore_existing_session(sid, session_id, emit_fn, emit_call_fn, environ):
+def _session_owner_matches_user(
+    session: WebsocketSession, user: User | PersistedUser | None
+) -> bool:
+    if session.user is None and user is None:
+        return True
+
+    if session.user is None or user is None:
+        return False
+
+    return session.user.identifier == user.identifier
+
+
+def restore_existing_session(
+    sid,
+    session_id,
+    emit_fn,
+    emit_call_fn,
+    environ,
+    user: User | PersistedUser | None = None,
+):
     """Restore a session from the sessionId provided by the client."""
     if session := WebsocketSession.get_by_id(session_id):
+        if not _session_owner_matches_user(session, user):
+            logger.error("Authorization for the session failed.")
+            raise ConnectionRefusedError("authorization failed")
+
# Source: https://github.com/Chainlit/chainlit/commit/5effb664f1e0af4a4f0a42fe63ea979676039a7f

The patch introduces _session_owner_matches_user, which compares the stored session's user identifier against the user resolved from the current connection. Mismatches now raise ConnectionRefusedError("authorization failed").

Detection Methods for CVE-2026-56104

Indicators of Compromise

  • WebSocket connections from unexpected source IP addresses reusing a sessionId previously bound to a different IP or user agent
  • Application logs showing successful restore_existing_session events without corresponding authentication events from the same client
  • Sudden geolocation or device fingerprint changes for an active Chainlit session
  • Anomalous tool invocations or thread access occurring outside normal user activity windows

Detection Strategies

  • Correlate Chainlit access logs with authentication events to identify session restorations that lack a fresh login from the same client identity
  • Monitor for repeated restore_existing_session calls referencing the same sessionId from differing client identifiers
  • Flag post-patch occurrences of the "Authorization for the session failed." log line, which indicates blocked hijack attempts
  • Inspect reverse proxy logs for WebSocket upgrade requests carrying session identifiers across distinct user contexts

Monitoring Recommendations

  • Centralize Chainlit application and WebSocket logs in your SIEM with user, session, and source IP fields normalized
  • Alert on tool execution events that occur from a session whose source IP changed within the session lifetime
  • Track session lifetimes and invalidate or rotate sessions that exceed expected duration thresholds

How to Mitigate CVE-2026-56104

Immediate Actions Required

  • Upgrade Chainlit to version 2.10.1 or later, which enforces session ownership validation on WebSocket restoration
  • Invalidate all active Chainlit sessions after upgrading to ensure no pre-existing hijacked sessions persist
  • Audit recent Chainlit activity logs for unauthorized tool invocations or thread access
  • Restrict network exposure of Chainlit deployments to authenticated reverse proxies or VPN-only access where feasible

Patch Information

The fix is delivered in the Chainlit 2.10.1 release via pull request #2857 and commit 5effb664. The patch adds the _session_owner_matches_user check to restore_existing_session, refusing the connection when the resolved user does not match the session owner. Additional details are available in the VulnCheck advisory.

Workarounds

  • Place Chainlit behind a reverse proxy that enforces per-connection authentication and rejects WebSocket upgrades lacking valid credentials
  • Shorten session lifetimes and rotate session identifiers frequently to reduce the window for hijack reuse
  • Restrict access to the Chainlit instance using network controls such as IP allowlists, mTLS, or zero-trust gateways until the upgrade is applied
bash
# Upgrade Chainlit to the patched release
pip install --upgrade "chainlit>=2.10.1"

# Verify installed version
python -c "import chainlit; print(chainlit.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.