Remote Code Execution via Deserialization of Maliciously Crafted Agent State in LangChain
Overview
A critical remote code execution (RCE) vulnerability, dubbed 'AgentState-Jacking,' was identified in the LangChain framework's core agent executor module. The vulnerability is triggered by the insecure deserialization of agent 'scratchpad' data when using certain storage backends for persisting conversational state, most notably Redis or file systems using Python's native `pickle` module. An attacker who gains write access to this storage backend—even without direct access to the application server—can inject a maliciously crafted payload. When a LangChain agent attempts to resume a conversation or an intermediate step, it deserializes this poisoned state object. The payload is designed to execute a `__reduce__` method, which can instantiate arbitrary classes and call any function, leading to code execution with the permissions of the Python process running LangChain. This is particularly dangerous in multi-tenant environments where a compromise in one user's state could lead to a full server takeover. The root cause is the reliance on `pickle`, a powerful but notoriously unsafe serialization format, without cryptographic signing or integrity checks. The discovery emphasizes the need for AI frameworks to default to safer, data-only serialization formats like JSON for handling agent state and tool outputs.
Affected Systems
Testing Guide
1. **Configure Vulnerable Setup**: Set up a LangChain agent using a version prior to 0.3.5, configured with a `PickleSerializer` and a Redis backend for memory. 2. **Generate Malicious Payload**: Create a Python script to generate a pickle payload that executes a command, for example, `os.system('touch /tmp/pwned')`. Use a tool like `pickletools` to create the payload. 3. **Inject Payload**: Connect to the Redis instance and manually write the malicious pickle payload to the key where the agent's state is stored. 4. **Trigger Deserialization**: Interact with the LangChain application in a way that causes it to load the persisted state from Redis. 5. **Verify Execution**: Check if the file `/tmp/pwned` has been created on the server running the LangChain application. Its presence confirms successful RCE.
Mitigation Steps
1. **Upgrade LangChain**: Immediately upgrade to LangChain version 0.3.5 or later, which defaults to a safe JSON-based serializer for agent state. 2. **Use Safe Serializers**: If unable to upgrade, explicitly configure your agent's memory or state persistence layer to use a safe serializer like `JSONSerializer` instead of the default `PickleSerializer`. 3. **Secure the Backend**: Restrict access to the state persistence backend (e.g., Redis, database, file system) to only the trusted application server. Implement strong authentication and network policies. 4. **State Signing**: As an additional defense-in-depth measure, wrap the serialization process with a cryptographic signature (e.g., using HMAC) to ensure the integrity and authenticity of the agent state before deserialization.
Patch Details
LangChain version 0.3.5 switches the default serializer to a safe alternative and removes pickle-based serialization for agent state.