LangChain Agent Executor Remote Code Execution via Deserialization Gadget in Custom Tool
Overview
A critical remote code execution vulnerability was discovered in applications utilizing LangChain's Agent Executor component, specifically when paired with custom tools that perform unsafe data deserialization. The attack vector allows an adversary to execute arbitrary code on the host server by exploiting how the agent processes data retrieved from external sources. The attack chain begins when an attacker crafts an indirect prompt injection payload and places it in a data source that the LangChain agent is expected to query, such as a web page, a database record, or a document in a vector store. When a legitimate user prompt triggers the agent to access this poisoned data source via a tool, the agent's LLM incorporates the malicious instructions into its reasoning process. These instructions guide the agent to use a different, seemingly benign custom tool, for example, a data analysis tool, but to pass it a specific parameter. This parameter, when processed by the tool, is revealed to be a serialized Python object using `pickle`. If the custom tool developer has insecurely used `pickle.loads()` to deserialize this data, the attacker's payload is executed with the permissions of the LangChain application. This bypasses typical prompt sanitization filters as the payload is delivered through a trusted tool's data channel, not the initial user prompt. The impact is a complete system compromise, enabling data exfiltration, lateral network movement, and the deployment of persistent malware. This finding underscores the critical need for developers to treat any data processed by LLM agents as untrusted and to avoid dangerous functions like `pickle.loads` or `exec` in tool implementations.
Affected Systems
Testing Guide
1. Statically analyze your codebase for the use of potentially dangerous functions like `pickle.loads`, `eval`, `exec` within any class that inherits from LangChain's `BaseTool`. 2. Create a test case where a tool retrieves data from a mock external source. 3. Place a benign pickled object (e.g., one that prints a message to stdout) in the mock source. 4. Trigger the agent to use the tool and process the mock data. 5. If the message is printed to stdout, your custom tool is vulnerable to deserialization attacks and needs to be remediated.
Mitigation Steps
1. Upgrade LangChain to version `0.2.8` or newer. 2. Audit all custom tools used by LangChain agents. Replace any use of `pickle.loads()`, `eval()`, or `exec()` with safer alternatives like `json.loads()` for data interchange. 3. Never deserialize data from untrusted sources. Treat all data retrieved by agent tools from external APIs, databases, or documents as untrusted. 4. Run LangChain applications in sandboxed environments (e.g., containers with minimal privileges, gVisor, Firecracker) to limit the impact of a potential code execution vulnerability.
Patch Details
LangChain version 0.2.8 introduced warnings and safe tool alternatives to discourage insecure practices.