Summary
langgraph-sdk constructs HTTP request paths for resource operations by interpolating caller-supplied identifier values into URL templates. Without sanitization of those values, identifiers that contain characters with special meaning in URL paths could cause the resulting request to address a different resource (and potentially a different resource type) than the SDK method's call site indicates. In deployments where the SDK receives identifier values that originate from untrusted sources, this could result in unintended access, modification, or deletion of resources beyond the calling user's authorization scope.
This issue is most consequential in deployments that:
- forward end-user-supplied values directly into SDK identifier parameters without first validating them against an expected format (such as a UUID), and - rely on URL-prefix-based authorization at an upstream layer (reverse proxy, edge gateway, WAF), where the authorization decision is made on the SDK call's intended path rather than on the final delivered request path.
There have no evidence of this behavior being triggered in the wild. This change is intended to reduce the surface available when caller-supplied identifier values originate from untrusted sources.
Affected users / systems
You may be affected if you:
- use langgraph-sdk (Python) to address resources by identifier, and - pass identifier values into SDK methods that originate from end-user input, untrusted third-party callers, or any source that does not validate identifier format before the SDK call.
Applications that validate identifier values (for example, by parsing them as UUIDs and rejecting anything that does not parse) before passing them to SDK methods are not affected. Validated UUIDs round-trip through the SDK request path unchanged.
Impact
- Potential unintended access, modification, or deletion of resources via SDK methods called for a different resource type, when caller-supplied identifier values are not validated. - In deployments with prefix-based authorization at an upstream layer, the authorization decision and the final delivered request path may diverge. - Confidentiality: disclosure of resource content beyond the authorization scope of the calling user. - Integrity: modification or deletion of resources beyond the authorization scope of the calling user.
Patches / mitigation
The SDK now applies path-segment encoding to identifier values before they are interpolated into request URL templates. After this change, identifier values that contain characters with special meaning in URL paths are transmitted as encoded byte sequences and routed to the resource the SDK method's call site indicates.
Compatibility
Identifier values that match the standard UUID format, or any other format that contains only characters safe to transmit unencoded in URL path segments, round-trip through the SDK request path unchanged. Applications that already validate identifier inputs see no behavioral change.
Operational guidance
- Validate identifier values (typically as UUIDs) at the boundary where untrusted input enters the application, before passing them to SDK methods. - For deployments relying on URL-prefix-based authorization upstream of LangGraph, prefer authorization at the LangGraph server layer or on parsed-and-validated request paths rather than on raw URL prefixes.
LangSmith / hosted deployments note
This issue affects the SDK that runs in caller applications. The LangGraph server runtime, including LangSmith-hosted deployments, receives ordinary HTTP requests on documented routes and is not itself affected by this issue. Applications that consume LangSmith-hosted services via langgraph-sdk and pass untrusted identifier values to SDK methods should upgrade.
First reported by: pucagit (CyStack).
LangGraph checkpointers can load msgpack-encoded checkpoints that reconstruct Python objects during deserialization. If an attacker can modify checkpoint data in the backing store (for example, after a database compromise or other privileged write access to the persistence layer), they can potentially supply a crafted payload that triggers unsafe object reconstruction when the checkpoint is loaded.
This is a post-exploitation / defense-in-depth issue. Exploitation requires the ability to write attacker-controlled checkpoint bytes at rest. In most deployments that prerequisite already implies a serious incident; the additional risk is turning “checkpoint-store write access” into code execution in the application runtime, which can expand blast radius (for example by exposing environment variables or cloud credentials available to the runtime).
There is no evidence of exploitation in the wild, and LangGraph is not aware of a practical exploitation path in existing deployments today. This change is intended to reduce the blast radius of a checkpoint-store compromise.
Affected users / systems
Users may be affected if they:
- use a persistent checkpointer (database, remote store, shared filesystem, etc.), - load/resume from checkpoints, and - operate in an environment where an attacker could gain privileged write access to checkpoint data in the backing store.
This issue requires the attacker to be able to modify persisted checkpoint bytes (or to compromise a trusted component that writes them). It is generally not reachable by an unauthenticated remote attacker in a correctly configured deployment.
Impact - Potential arbitrary code execution or other unsafe side effects during checkpoint deserialization. - Escalation from “write access to checkpoint store” to “code execution in the application runtime,” which may expose runtime secrets or provide access to other systems the runtime can reach.
Exploitation scenario (high level) 1. Attacker gains privileged write access to the checkpoint store (for example, via database compromise, leaked credentials, or abuse of an administrative data path). 2. Attacker writes a crafted checkpoint payload containing msgpack data intended to reconstruct dangerous objects. 3. Application resumes and deserializes the checkpoint; unsafe reconstruction could execute attacker-controlled behavior.
Mitigation / remediation LangGraph provides an allowlist-based hardening mechanism for msgpack checkpoint deserialization.
Strict mode (environment variable) - LANGGRAPHSTRICTMSGPACK - When set truthy (1, true, yes), the default msgpack deserialization policy becomes strict. - Concretely: JsonPlusSerializer() will default allowedmsgpackmodules to None (strict) instead of True (warn-and-allow), unless allowedmsgpackmodules=... is explicitly passed.
allowedmsgpackmodules (serializer/checkpointer config) This setting controls what msgpack “ext” types are allowed to be reconstructed.
- True (default when strict mode is not enabled): allow all ext types, but log a warning when deserializing a type that is not explicitly registered. - None (strict): only a built-in safe set is reconstructed; other ext types are blocked. - [(module, classname), ...] (strict allowlist): the built-in safe set plus exactly the listed symbols are reconstructed (exact-match).
Built-in safe set A small set of types is always treated as safe to reconstruct (for example datetime types, uuid.UUID, decimal.Decimal, set/frozenset/deque, ipaddress types, pathlib paths, zoneinfo.ZoneInfo, compiled regex patterns, and selected LangGraph internal types).
Automatically derived allowlist (only when compiling graphs) When LANGGRAPHSTRICTMSGPACK is enabled and StateGraph is compiled, LangGraph derives an allowlist from the graph’s schemas and channels and applies it to the checkpointer.
- The allowlist is built by walking the state/input/output/context schemas (plus node/branch input schemas) and channel value/update types. It includes Pydantic v1/v2 models, dataclasses, enums, TypedDict field types, and common typing constructs (containers, unions, Annotated). - LangGraph also includes a curated set of common LangChain message classes.
This derived allowlist is only applied if the selected checkpointer supports withallowlist(...). If a user is constructing serializers/checkpointers manually (or using a checkpointer that does not support allowlist propagation), they will need to configure allowedmsgpackmodules themselves.
Operational guidance - Treat checkpoint stores as integrity-sensitive. Restrict write access and rotate credentials if compromise is suspected. - Enable strict mode (LANGGRAPHSTRICTMSGPACK=true) in production if feasible, and rely on schema-driven allowlisting to reduce incompatibilities. - Avoid providing custom msgpack deserialization hooks that reconstruct arbitrary types unless checkpoint data is fully trusted.
Limitations / important notes - If a checkpointer implementation does not support allowlist application (i.e., does not implement withallowlist), allowlist enforcement may be skipped (with a warning). In that situation, strict expectations may not hold. - If an application supplies a custom msgpack unpack hook (exthook), the custom hook controls reconstruction and can bypass the default allowlist checks (intentional escape hatch, but it weakens the protection).
LangSmith / hosted deployments note LangSmith is not aware of this issue presenting risk to existing LangSmith-hosted deployments. The described threat model requires an attacker to tamper with the checkpoint persistence layer used by the deployment; typical hosted configurations are designed to prevent such access.
First reported by: yardenporat353
Summary
LangGraph's JsonPlusSerializer can reconstruct Python objects from JSON checkpoint payloads. Under conditions where someone could modify checkpoint bytes at rest in the backing store, the deserialization path could reconstruct objects beyond what the application expects, which could in turn result in code execution at checkpoint load time.
This is a defense-in-depth issue. The affected behavior is reachable only when checkpoint bytes at rest in the backing store can be modified by an unauthorized party. In most deployments that prerequisite already implies a serious incident; the additional concern is turning "checkpoint-store write access" into code execution in the application runtime.
There is no evidence of this behavior being triggered in the wild, and the team is not aware of a practical path to it in existing deployments today. This change is intended to reduce the surface available after a checkpoint-store incident.
Affected users / systems
Users may be affected if they:
- use a persistent checkpointer (database, remote store, shared filesystem, etc.) with the default JsonPlusSerializer, - load/resume from checkpoints, and - operate in an environment where write access to the checkpoint store could be obtained by an unauthorized party.
The default checkpoint serializer in all shipped checkpointer backends (PostgresSaver, SqliteSaver, and their async counterparts) is JsonPlusSerializer, so applications generally do not need to opt in to be in scope.
Impact
- Potential arbitrary code execution or other unsafe side effects during checkpoint deserialization. - Escalation from "write access to the checkpoint store" to "code execution in the LangGraph worker process," which may expose runtime secrets or provide access to other systems the runtime can reach.
Patches / mitigation
The JSON deserialization path has been narrowed so that revival is restricted to default-constructor reconstruction using the args/kwargs carried in the payload. The framework's own encoder has not relied on the removed behavior for produced checkpoints since the msgpack migration, so this change does not affect freshly written checkpoints. Legacy payloads that already used the default constructor as their first option continue to revive correctly via that same path.
Compatibility
A narrow legacy-resume regression applies to pre-October-2025 checkpoints of pydantic models where the original payload depended on a no-validation fallback factory to recover from incompatible schema evolution. After this change, such payloads return None from the revival path and fall through to the langchain-core reviver, which surfaces the raw dict rather than reconstructing the model.
Operational guidance
- Treat checkpoint stores as integrity-sensitive. Restrict write access and rotate credentials if unauthorized access is suspected. - Avoid providing custom JSON revival hooks that reconstruct arbitrary types unless checkpoint data is fully trusted.
LangSmith / hosted deployments note
The team is not aware of this issue presenting concern for existing LangSmith-hosted deployments. The described conditions require modification of the checkpoint persistence layer used by the deployment; typical hosted configurations are designed to prevent such access.
First reported by: pucagit (CyStack).