| Titolo | NousResearch Hermes Agent <= v2026.4.30 Insufficient Verification of Data Authenticity (CWE-345) |
|---|
| Descrizione | # Technical Details
A forged todo-tool history hydration vulnerability exists in the `AIAgent._hydrate_todo_store` method in `run_agent.py` of Hermes Agent.
The application fails to verify that `role="tool"` messages in caller-supplied `conversation_history` actually originated from the trusted todo tool. The HTTP API server accepts arbitrary `conversation_history` entries from requests and forwards them into `AIAgent.run_conversation()`. Fresh agent instances then invoke `_hydrate_todo_store()`, which trusts any prior tool message containing a `"todos"` JSON key and writes the parsed entries into `TodoStore` without provenance checks, item-size limits, or total-size limits. Later context-compression flows reinject active todos into the model context, allowing an API client to persist oversized forged todo state and force session-level denial of service.
# Vulnerable Code
File: `gateway/platforms/api_server.py`
Method: API request handling for `/v1/responses`
Why: The API server accepts attacker-controlled `conversation_history` entries from the request body and forwards them into `run_conversation()` without distinguishing trusted tool output from user-supplied content.
File: `run_agent.py`
Method: `AIAgent.run_conversation`
Why: The method invokes `_hydrate_todo_store(conversation_history)` on fresh agent instances when the todo store has no items.
File: `run_agent.py`
Method: `_hydrate_todo_store`
Why: The method scans prior history for any `role="tool"` message containing `"todos"`, parses it, and writes it into `TodoStore` without verifying tool provenance.
File: `tools/todo_tool.py`
Method: `TodoStore.write`
Why: The method accepts replayed todo items and persists them without enforcing total-size or per-item character-length limits.
File: `tools/todo_tool.py`
Method: `format_for_injection`
Why: The method converts every active todo entry into prompt text for later context reinjection, amplifying oversized hydrated content into future context windows.
# Reproduction
1. Start Hermes Agent with the API server enabled using `hermes model` and `API_SERVER_ENABLED=true hermes gateway run`.
2. Download the PoC script from `https://gist.github.com/YLChen-007/df3c25cc5a4a7c4bee0666f3abd6d864`.
3. Run `python3 poc_exploit.py --base-url http://127.0.0.1:8642`.
4. If authentication is required, run `python3 poc_exploit.py --base-url http://127.0.0.1:8642 --api-key "$API_SERVER_KEY"`.
5. Download the control script from `https://gist.github.com/YLChen-007/c7ddd0fde27b802f1f32489ed465a2f8` and run the same request without a forged tool-history payload.
6. Download the direct verification script from `https://gist.github.com/YLChen-007/743a20065c6e9431a53d288683a2e434` and run `python3 poc_exploit_direct.py`.
7. Observe that a forged todo entry with a 50,001-character content string is accepted and later produces a 50,085-character context reinjection block.
# Impact
- Denial of Service against Hermes Agent sessions reachable through the API server.
- Attackers with API access can poison per-session todo state with oversized forged tool output.
- Subsequent requests for the affected session may suffer persistent context inflation, degraded model behavior, or request failure.
- The issue affects service availability and session integrity without requiring direct code execution. |
|---|
| Fonte | ⚠️ https://gist.github.com/YLChen-007/b91a85f9448beadebe25d37a3f4fd760 |
|---|
| Utente | Eric-a (UID 96353) |
|---|
| Sottomissione | 02/06/2026 03:34 (1 mese fa) |
|---|
| Moderazione | 03/07/2026 19:08 (1 month later) |
|---|
| Stato | Accettato |
|---|
| Voce VulDB | 376142 [NousResearch hermes-agent fino a 2026.4.30 HTTP API run_agent.py AIAgent.run_conversation todos negazione del servizio] |
|---|
| Punti | 20 |
|---|