| Titre | OpenBMB XAgent v1.0.0 Authorization Bypass Through User-Controlled Key (CWE-639) |
|---|
| Description | # Technical Details
An Insecure Direct Object Reference (IDOR) vulnerability exists in the `ReplayServer.on_connect()` and `ReplayServer.send_data()` methods in `XAgentServer/application/websockets/replayer.py` (lines 109-115, 173-195) of XAgent.
The application fails to verify ownership of the requested `interaction_id` in the `/ws/replay/{interaction_id}` WebSocket endpoint. The `check_user()` call only validates that the connecting user has a valid token, but never checks whether the user owns the requested interaction. Combined with the unmasked storage of `api_key` in the MySQL `raw` table (from `function_handler.py:275-281`), any authenticated user can replay another user's past interactions and extract their third-party API keys.
# Vulnerable Code
File: XAgentServer/application/websockets/replayer.py (lines 109-115)
Method: on_connect()
Why: `check_user()` validates the connecting user's token but never verifies ownership of `self.client_id` (the `interaction_id` from URL path).
File: XAgentServer/application/websockets/replayer.py (lines 173-195)
Method: send_data()
Why: Calls `search_many_raws(interaction_id=self.client_id)` - the attacker-controlled `interaction_id` is used directly in the database query with no ownership filter.
File: XAgentServer/database/interface/interaction.py (lines 394-406)
Method: search_many_raws()
Why: Filters only by `interaction_id` - no `user_id` check, returns all records to any caller.
File: XAgent/function_handler.py (lines 275-281)
Why: Stores `api_key` in plaintext in `using_tools["tool_input"]`, which flows to the MySQL `raw` table.
# Reproduction
1. Deploy XAgent via Docker (`docker compose up -d`).
2. Victim runs a task that invokes any RapidAPI tool with `api_key` - this is stored unmasked in the `raw` table.
3. Attacker logs in with their own account (default `guest/xagent`).
4. Attacker connects to `/ws/replay/{victim_interaction_id}` via WebSocket.
5. Attacker sends `{"type": "replay"}` - server streams ALL raw records of the victim's interaction, including plaintext `api_key`.
# Impact
- Cross-user credential theft: Any authenticated user can steal third-party API keys from any other user's past interactions.
- Complete interaction history exposure: Attacker can read goals, plans, tool arguments, and results of any user.
- Systematic harvesting: Attacker can enumerate interaction IDs and harvest credentials at scale. |
|---|
| La source | ⚠️ https://gist.github.com/YLChen-007/dc46c2a710ecb9e855695f32da8bcab5 |
|---|
| Utilisateur | Eric-z (UID 95890) |
|---|
| Soumission | 11/03/2026 14:06 (il y a 20 jours) |
|---|
| Modérer | 27/03/2026 09:08 (16 days later) |
|---|
| Statut | Accepté |
|---|
| Entrée VulDB | 353835 [OpenBMB XAgent 1.0.0 WebSocket Endpoint replayer.py ReplayServer.on_connect/ReplayServer.send_data interaction_id élévation de privilèges] |
|---|
| Points | 20 |
|---|