14 min read
High
By

LangGraph flaw chain: how a checkpointer SQL injection and an unsafe msgpack decoder turn self-hosted AI agents into remote code execution

13 June 2026. On 12 June Check Point Research disclosed three now-patched flaws in LangGraph, LangChain's open-source framework for stateful, multi-step AI agents. Two of them chain into a remote code execution: a SQL injection in the SQLite checkpointer inserts a forged row into the query results, and an unsafe msgpack decoder reconstructs an attacker-controlled object from it on load. Affected is anyone who self-hosts LangGraph and runs the checkpointer with user-controlled filter input — not the hosted LangSmith platform. Fixed in langgraph 1.0.10, langgraph-checkpoint-sqlite 3.0.1 and @langchain/langgraph-checkpoint-redis 1.0.1.

TL;DR — 90 seconds

Affected?

Self-hosted LangGraph deployments running the SQLite checkpointer (langgraph-checkpoint-sqlite < 3.0.1) or the Redis checkpointer (@langchain/langgraph-checkpoint-redis < 1.0.1) with user-controlled filter input, plus langgraph < 1.0.10 for the msgpack decoder. LangSmith-hosted deployments are not affected.

Risk?

Chained (CVE-2025-67644 + CVE-2026-28277) a remote code execution on the agent server: SQL injection in the checkpointer → forged checkpoint row → unsafe msgpack deserialization on load → code execution. Individually: SQLi of the metadata query (7.3), unsafe object reconstruction (6.8), RediSearch query injection with access-control bypass (6.5).

Immediate action?

Raise to langgraph ≥ 1.0.10, langgraph-checkpoint-sqlite ≥ 3.0.1 and @langchain/langgraph-checkpoint-redis ≥ 1.0.1. Do not expose the get_state_history() path without authentication; treat filter input like any other user-controlled input.

Recommendation?

The German Mittelstand and enterprise: apply with priority where a self-hosted LangGraph server processes external or semi-trusted filter input; the agent server should be treated as a privileged identity, not an internal helper service.

Criticality?

high (references the hero badge — chained RCE, but bound to a self-hosted setup, an exposed path and user-controlled filter; no known mass exploitation).

 

What is the problem?

LangGraph models agents as a state machine: every step an agent takes is persisted as a checkpoint, so that a run can pause, resume, branch and read back its own history. That memory lives in a pluggable store — the checkpointer — commonly on SQLite or Redis. That is exactly where the three flaws Check Point Research disclosed on 12 June sit. The crucial point is not exotic but old: these are classic vulnerability classes (SQL injection, unsafe deserialization, query injection) landing in a component that carries elevated rights and trust — the store from which an agent loads its own past.

The most severe effect comes from a chain. CVE-2025-67644 (CVSS 7.3) is a SQL injection in the SQLite checkpointer: via metadata filter keys the query LangGraph issues to fetch historical checkpoints can be manipulated. CVE-2026-28277 (CVSS 6.8) is an unsafe msgpack deserialization: when loading a checkpoint, LangGraph reconstructs an object from the stored BLOB without treating its contents as untrusted. On its own, LangGraph rates the second flaw a post-exploitation weakness — it requires an attacker who can already write checkpoint data. The SQL injection delivers exactly that precondition for free: it inserts a forged checkpoint row with an attacker-controlled BLOB into the result set, which the decoder then reconstructs unsuspectingly.

The third flaw, CVE-2026-27022 (CVSS 6.5), is a RediSearch query injection in the Redis checkpointer (@langchain/langgraph-checkpoint-redis). It allows search queries to be manipulated so that access controls are bypassed — for example fetching checkpoints across the intended tenant or thread boundary. It is not part of the RCE chain, but belongs in the same view because it hits the same architectural reflex: filter input that flows unchecked into a query against the agent store.

Who is affected?

ComponentStatusCondition
langgraph < 1.0.10Affected (CVE-2026-28277)Fix in 1.0.10 — unsafe msgpack deserialization on checkpoint load
langgraph-checkpoint-sqlite < 3.0.1Affected (CVE-2025-67644)Fix in 3.0.1 — SQL injection via metadata filter keys
@langchain/langgraph-checkpoint-redis < 1.0.1Affected (CVE-2026-27022)Fix in 1.0.1 — RediSearch query injection / access-control bypass
Self-hosted with exposed get_state_history()Fully exposed (RCE chain)SQLite or Redis checkpointer and user-controlled filter input
LangSmith-hosted (managed)Not affectedThe hosted platform's persistence layer is designed against foreign write access
In-memory checkpointer (no SQLite/Redis)Not affected by 67644/27022still pull langgraph ≥ 1.0.10 (28277)

The dividing line runs along self-hosting plus user-controlled filter input. The full chain bites where a self-operated LangGraph server makes the get_state_history() path reachable and accepts filter values from a not-fully-trusted source, for example an agent endpoint that passes end-user or tenant input into the checkpoint query. Anyone running LangGraph purely internally, without an exposed history retrieval and without foreign filter input, has a lower acute risk but closes the gap with the same update. LangSmith-hosted deployments are, per the maintainers, not affected, because the hosted persistence layer prevents the foreign write access to the checkpoint store that the chain requires.

Impact

The reliably reachable worst case of the chain is code execution in the agent's runtime context. That is serious because an AI agent is rarely a bare compute object: it usually holds API keys, model tokens, database access and often far-reaching tools. LangGraph states the escalation soberly (from write access to the checkpoint store to code execution) and names the consequence: runtime secrets may be exposed, and the agent can serve as a springboard to further systems its runtime can reach. Put differently: whoever compromises the agent inherits its permissions, not just its compute time.

The honest reading of severity: the individual CVSS scores sit in the high/medium range (7.3, 6.8, 6.5), not at 9+. The RCE arises only through the chaining and is bound to concrete preconditions: self-hosted, an exposed history path, user-controlled filter, a SQLite or Redis checkpointer. Where these conditions meet, the pressure to act is high; where they do not, it remains a regular but prompt update. Check Point puts the overarching lesson precisely: a long-known vulnerability class such as SQL injection becomes more dangerous when it surfaces inside an AI agent framework that carries elevated rights and trust. The class is not new — the place where it bites is.

Mitigation / immediate steps

Now: raise the affected packages to the patched line

 

# Python stack (SQLite checkpointer + core)
pip install -U "langgraph>=1.0.10" "langgraph-checkpoint-sqlite>=3.0.1"

# or with uv
uv pip install -U "langgraph>=1.0.10" "langgraph-checkpoint-sqlite>=3.0.1"

# JS/TS stack (Redis checkpointer)
npm install @langchain/langgraph-checkpoint-redis@^1.0.1

# Verify installed versions
pip show langgraph langgraph-checkpoint-sqlite 2>/dev/null | grep -E 'Name|Version'
npm ls @langchain/langgraph-checkpoint-redis

 

Do not expose the history path unprotected

 

# get_state_history() (or the endpoint that calls it) belongs behind authentication.
# Filter / metadata values are user-controlled input — never pass them unchecked into
# the checkpoint query. Where possible, constrain filter fields server-side to an
# allow-list of known keys instead of accepting arbitrary metadata keys.

 

If an update is not immediately possible (stopgaps, no substitute for the patch)

 

# 67644 / 27022: force filter input to a fixed allow-list of metadata keys before the
#                checkpoint query; block free-form filter expressions from
#                user-controlled sources.
# 28277:         seal the checkpoint store against foreign write access — no writing
#                path from an untrusted source onto the SQLite file or the Redis keys
#                of the checkpointer.
# General:       keep get_state_history()-adjacent endpoints internal/authenticated for now.

 

LangGraph explicitly rates CVE-2026-28277 a post-exploitation problem — the deserialization only becomes a weapon once an attacker can write checkpoint data. That is not cause for an all-clear but the lever of mitigation: whoever keeps the write path to the checkpoint store sealed and tames filter input removes the RCE chain's precondition, even before every package is updated. The update remains mandatory; constraining write access is the more robust, durable line.

Detection / verification

Establish inventory: who runs which checkpointer at which version?

 

# Scan Python projects in the estate for affected packages
grep -rnE 'langgraph-checkpoint-sqlite|langgraph\b' --include='requirements*.txt' \
  --include='pyproject.toml' --include='uv.lock' --include='poetry.lock' path/to/repos

# Scan JS/TS projects for the Redis checkpointer
grep -rn '@langchain/langgraph-checkpoint-redis' --include='package*.json' path/to/repos

# Running environment
pip show langgraph langgraph-checkpoint-sqlite 2>/dev/null | grep -E 'Name|Version'

 

Code path: is filter input from a user-controlled source passed into the history retrieval?

 

# Find calls to the history retrieval and the metadata filters
grep -rnE 'get_state_history|aget_state_history|\.filter\b|metadata_filter' \
  --include='*.py' --include='*.ts' --include='*.js' path/to/app

# Counter-check: is the filter fed from request / end-user input?
grep -rnE 'request\.(args|json|query)|req\.(body|query|params)' \
  --include='*.py' --include='*.ts' path/to/app

 

Acceptance after the patch

 

# Confirm versions after update (target: 1.0.10 / 3.0.1 / 1.0.1)
pip show langgraph langgraph-checkpoint-sqlite 2>/dev/null | grep Version
npm ls @langchain/langgraph-checkpoint-redis

# Regression test in an isolated test environment only:
# - a crafted metadata filter must no longer return a foreign/forged checkpoint row
# - a tampered checkpoint BLOB must no longer reconstruct an object on load
#   (verify on the patched state — do not use live data)

Operator recommendation

Operational Decision Block:

The German Mittelstand

If you run an AI agent yourself, treat the agent server like a privileged identity, not an internal helper service: authentication in front of the history retrieval, no long-lived static secrets in the agent runtime, network segmentation between the agent and the rest of your systems. Then answer the one question this chain really poses: does end-user or tenant input reach the checkpoint query unchecked as a filter anywhere? If so, the durable hardening is the allow-list at the filter level, not just the update.

Enterprise / multi-tier fleets

Capture the LangGraph estate by inventory (SBOM, lockfiles) instead of by sampling — the checkpointer often sits as a transitive dependency inside agent services. Seal write paths onto SQLite files and the checkpointer's Redis keys against foreign access; enforce tenant separation against the RediSearch query injection (27022) server-side as well, not by the search expression alone.

Kubernetes / declarative stacks

Roll out patched images with the new package states via the registry and pin them by digest. Separate the checkpoint store (Redis/SQLite PVC) from uncontrolled write access by NetworkPolicy and RBAC. Remember: a rolling restart is needed so the pods load the patched libraries.

What we did concretely

We checked the advisory against our estate on the day it appeared. The first question was not “do we use LangGraph?” but “where does an agent run self-hosted, which checkpointer does it use, and does foreign filter input reach it?”. Because our agent services are inventoried via lockfiles and image digests, the version and topology question was answered in minutes rather than by per-service sampling. The affected package states are raised, and the history retrieval sits — where it is exposed at all — behind authentication; filter fields are constrained server-side to known keys instead of accepting arbitrary metadata keys.

The lesson learned is an architectural statement, not a single measure: the dangerous thing about this chain is not “LangGraph is insecure” but that a classic SQL injection lands in the memory layer of an agent, that is, where trust and rights are bundled. Patching closes the three concrete spots; the durable hardening closes the class: user-controlled filter input is forced onto allow-lists, the write path to the checkpoint store is sealed against foreign access, and the agent is treated as a privileged identity with a minimal rights footprint. This is exactly where it pays off that we build self-hosted AI for the German Mittelstand not as a convenience but as sovereignty: whoever owns the agent must also protect it like a privileged system — and can, because storage, network and secrets are within their own reach.

Frequently asked questions about the LangGraph flaw chain

Are we affected if we only use LangGraph via LangSmith (managed)?+

Per the maintainers, no — the RCE chain and the checkpointer flaws hit self-hosted deployments with a SQLite or Redis checkpointer and user-controlled filter input. LangSmith-hosted deployments are not affected, because the hosted persistence layer prevents the foreign write access required. Anyone mixing both (managed plus their own self-hosted agents) should check the self-hosted side.

We use the in-memory checkpointer, not SQLite or Redis. Do we still need to patch?+

The SQL injection (CVE-2025-67644) and the RediSearch injection (CVE-2026-27022) then do not affect you. But the unsafe msgpack deserialization (CVE-2026-28277) sits in the core langgraph package — so pull langgraph ≥ 1.0.10 in any case as soon as checkpoints are loaded from a source not fully under your control.

Which versions close all three flaws?+

langgraph ≥ 1.0.10 (msgpack deserialization), langgraph-checkpoint-sqlite ≥ 3.0.1 (SQL injection) and @langchain/langgraph-checkpoint-redis ≥ 1.0.1 (RediSearch query injection). Depending on which checkpointer you run, you need the core package plus the matching checkpointer patch.

Why is a “normal” SQL injection so critical here?+

Because it sits in the memory layer of an AI agent. The SQLi inserts a forged checkpoint row with an attacker-controlled BLOB into the results; the unsafe msgpack decoder reconstructs an object from it on load — and the agent runs with elevated rights and tokens. A long-known class becomes more dangerous because the place where it bites carries trust and permissions.

Is the update enough, or do we have to change something in the setup?+

The update is mandatory and closes the three spots. The durable hardening sits one level deeper: do not expose get_state_history() unauthenticated, constrain filter input to an allow-list of known metadata keys, and seal the write path to the checkpoint store against foreign access. That removes the chain's precondition, not just the concrete flaw.

How should we secure our self-hosted agent in general?+

Treat it as a privileged identity: authentication in front of the history retrieval, no long-lived static secrets in the runtime, network segmentation between the agent and the rest of your systems, and the principle of least privilege for every token and tool the agent is allowed to hold. That is the same discipline LangGraph recommends in the mitigations — and it pays off beyond this one flaw.

Conclusion

The LangGraph chain is not a fire alarm for everyone, but a mandatory appointment for anyone who self-hosts AI agents. Three old vulnerability classes (SQL injection, unsafe deserialization, query injection) hit the memory layer of an agent here, and two of them chain into a remote code execution on the agent server. The severity should be read honestly: high individual scores, RCE only under concrete preconditions (self-hosted, an exposed history path, user-controlled filter, a SQLite or Redis checkpointer), LangSmith-hosted not affected. Whoever meets those conditions acts within the 48-hour window; whoever runs LangGraph purely internally applies the update in the running cycle. The durable lesson sits one level deeper than the patch: an AI agent is not a helper service but a privileged identity. Patching closes the spot; treating the agent as a privileged system (filter on an allow-list, write path sealed, least privilege) closes the class.

Sources

Before your agent loads its own past against you — let’s talk about privileged identity instead of helper service.

We inventory, patch and harden your self-hosted AI agents against the LangGraph chain — and check where user-controlled filter input runs unchecked into the checkpoint store.

We run the version and topology inventory via lockfiles and image digests (not just package states), raise the affected packages, put the history retrieval behind authentication and force filter input onto an allow-list. We then set the agent up as a privileged identity: no long-lived static secrets in the runtime, network segmentation, least privilege.

Platform operations instead of advice-on-paper: we review, mitigate and validate productive agent stacks — from the LangGraph inventory through sealing the checkpoint store to the filter allow-list.

Book an appointment directly

About the author

[Translate to English:] Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Founder · Moselwal Digitalagentur · OnlyOle

Programming since 2002 – self-taught, set up my own business with KO-Web in 2012, now Moselwal. Over 100 projects, with a focus on security, performance, automation and quality.