| Title | NousResearch Hermes Agent <= v2026.5.16 Path Traversal / Improper Limitation of a Pathname to a Restricted Directory (CWE-22) |
|---|
| Description | # Technical Details
An Arbitrary File Read of whitelisted-extension files exists in the `BasePlatformAdapter.extract_media` method in `gateway/platforms/base.py` of Hermes Agent.
The application fails to enforce directory containment or traversal checks on file paths extracted from `MEDIA:` tags in LLM response text. The `extract_media()` method matches absolute or home-relative paths ending in whitelisted extensions such as `.csv`, `.txt`, `.pdf`, `.zip`, `.docx`, `.xlsx`, `.epub`, media files, and archive formats. It then passes the extracted path through `os.path.expanduser()` and returns it for later attachment delivery. There is no call to containment helpers such as `validate_within_dir()` or traversal checks such as `has_traversal_component()`. An attacker who can influence the LLM output through prompt injection on any connected messaging platform can cause the gateway to read and send files from outside the agent sandbox, as long as the target path has an allowed extension.
# Vulnerable Code
File: `gateway/platforms/base.py`
Method: `BasePlatformAdapter.extract_media`
Why: The method extracts `MEDIA:<path>` values using a regex that accepts absolute and home-relative paths with whitelisted extensions, strips quotes/backticks, expands `~`, and appends the path to the media list without validating the resolved path against a safe base directory.
File: `gateway/platforms/base.py`
Method: `_process_message_background`
Why: The call site consumes extracted media paths and sends them as file attachments to the messaging platform without adding a later containment check.
# Reproduction
1. Start a Hermes Agent instance with a gateway platform configured, such as Webhook, Telegram, or Discord.
2. Create a sensitive file outside the agent sandbox with a whitelisted extension, for example `/tmp/poc_secret.csv`.
3. From the Hermes Agent project root, call `BasePlatformAdapter.extract_media("Here is the file:\nMEDIA:/tmp/poc_secret.csv")`.
4. Observe that the method returns `/tmp/poc_secret.csv` with no directory restriction.
5. Confirm that extension-less paths such as `MEDIA:/etc/passwd` are not matched under the current regex, while whitelisted-extension paths remain accepted.
6. For end-to-end webhook verification, download `test_gateway.py` from `https://gist.github.com/YLChen-007/d51923153cfa4983ae6174fd353e7efa`, configure a webhook route, and run `python test_gateway.py`.
7. For remote exploitation against a live webhook endpoint, download `poc_exploit.py` from `https://gist.github.com/YLChen-007/5df942cd180bd57a4aab5a774fb0d81b` and run it against the target webhook URL.
# Impact
- Arbitrary file read of files readable by the Hermes Agent process user when the path ends in a whitelisted extension.
- Attackers can exfiltrate `.csv` or `.xlsx` data exports, database dumps, `.zip` or `.7z` backups, `.pdf` or `.docx` documents, `.txt` configuration or log files, and other whitelisted-extension files from anywhere on the host filesystem.
- The gateway media-delivery path bypasses the agent's internal `validate_within_dir()`-based file access sandbox.
- Exploitation requires only the ability to send prompt-injection content through a connected gateway platform and does not require authentication beyond access to that messaging channel. |
|---|
| Source | ⚠️ https://gist.github.com/YLChen-007/8af7eff27b50bec24b2d0f76dd1c4383 |
|---|
| User | Eric-a (UID 96353) |
|---|
| Submission | 06/02/2026 03:37 (1 month ago) |
|---|
| Moderation | 07/03/2026 19:08 (1 month later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 376144 [NousResearch hermes-agent up to 2026.5.16 Live Webhook Endpoint base.py extract_media path traversal] |
|---|
| Points | 20 |
|---|