TL;DR
- Vulnerability: Unsanitized
eval()
in the agent’s memory filter leads to remote code execution (RCE). - Impact: Any chat prompt could trigger a server-side shell (CVSS 9.9 / Critical).
- Root cause: Combining user-supplied filter strings with Python
eval()
is an AI memory injection and prompt injection issue flagged in the OWASP LLM Top 10. - Fix: Drop raw
eval
, validate LLM tool calls like external input, and sandbox the runtime.
Background: Memory as an Attack Surface
Modern AI agents keep a running memory of prior conversations to deliver context-aware responses. If the agent lets users query or filter that memory, it opens a fresh vector for AI memory injection and prompt injection attacks. This pattern is explicitly called out in the draft OWASP LLM Top 10 under Prompt Injection and Excessive Agency.
Finding the Bug with Waclaude
While field-testing Waclaude, my AI vulnerability hunter, I pointed it at an open-source AI agent with over 11,000 ⭐ and 2,000 forks. In seconds, Waclaude spotted an unsanitized eval() powering the AI agents memory. A direct path to code execution:
def _get_comparator(condition: str):
def comparator(data: dict[str, Any]):
return eval(condition, {}, data) # user controlled
The condition
string arrives straight from a memory_filter argument produced by the LLM, making every user prompt a potential code payload.
Deep Dive: From Memory Filter to RCE
- A user prompt includes a malicious filter.
- The LLM emits a
memory_load
tool call containing that filter. - The agent forwards filter →
_get_comparator()
→eval()
with no validation. - Python executes arbitrary code under the agent’s privileges, resulting in full remote code execution.
Proof of Concept Payload
All it took was a single-line filter embedded in a chat prompt:
__import__("os").system('echo "pwned" > /tmp/proof.txt') or False
When the agent evaluated this filter, it wrote the file, proving code execution.
Disclosure
We filed an advisory the same day, shipped a patch PR and coordinated privately with the maintainers to ship the fix. Waclaude identified, exploited and patched the vulnerability in seconds.
Key Takeaways and Mitigation
What Happened | How to Prevent It |
---|---|
Raw eval() on user input | Replace with safe parsing (ast.literal_eval , vetted DSL) or whitelist operators. |
LLM tool calls treated as trusted | Validate and sanitize LLM output exactly like external user input. |
High privileges on the host | Run agents in containers with non-root users, read-only filesystems, and syscall filters such as seccomp or AppArmor. |
No automated testing for memory filters | Add unit tests and fuzzers that inject malicious strings into every filter path. |
If you’re shipping AI agents in production and want a second look at your security, let's chat!