#1561·SuperAGI

[Bug] Path Traversal leading to Arbitrary File Write/RCE in ReadEmail Tool

Author: QiuYucheng2003Created Jun 7, 2026Updated Jun 27, 2026

⚠️ Check for existing issues before proceeding. ⚠️

  • I have searched the existing issues, and there is no existing issue for my problem

Where are you using SuperAGI?

MacOS

Which branch of SuperAGI are you using?

Main

Do you use OpenAI GPT-3.5 or GPT-4?

GPT-4

Which area covers your issue best?

Tools

Describe your issue.

A critical Path Traversal vulnerability exists in the download_attachment function of superagi/helper/read_email.py.

The system extracts the attachment filename using part.get_filename() and directly concatenates it using os.path.join(folder_name, filename) without any sanitization. Because os.path.join does not block directory traversal sequences (../) and processes absolute paths by discarding the base path, an external attacker can send a malicious email with a crafted attachment name (e.g., ../../../../../../etc/cron.d/evil.service or /root/.ssh/authorized_keys).

When the agent executes the Read Email tool, it writes the attachment data to the attacker-controlled path, leading to Arbitrary File Overwrite and unauthenticated Remote Code Execution (RCE).

How to replicate your Issue?

Agent Config: Create any agent configured with the Read Email tool and valid IMAP credentials. Model selection does not affect this vulnerability.

Steps to replicate:

  1. From an external email account, send an email to the agent's configured inbox. Attach a payload file and intercept the request to rename the attachment to: ../../../../../../tmp/pwned.txt.

  2. Start the SuperAGI agent and prompt it to read the latest emails.

  3. The download_attachment function triggers.

  4. Check the host machine/container. The file will successfully escape the intended sandbox folder and be written to /tmp/pwned.txt.

Suggested Fix: Sanitize the extracted filename before path concatenation by stripping path traversal characters.

import os

...

filename = part.get_filename() if filename: # Fix: Extract only the base filename filename = os.path.basename(filename) if not filename: return

folder_name = self.clean(subject)
# ...
filepath = os.path.join(folder_name, filename)

Upload Error Log Content

N/A - Security Vulnerability discovered via static code analysis. Since this issue was identified through source code review rather than a runtime crash, there are no Docker error logs to provide. Furthermore, a successful Path Traversal / Arbitrary File Write attack typically executes silently at the OS level and does not throw standard application errors in the logs. Please refer to the "Steps to Reproduce" and the provided code snippet for verification.

Source: TransformerOptimus/SuperAGI