3 LangGraph CVEs chain to RCE: the checkpointer version matrix and a 30-minute audit

Three patched LangGraph CVEs turn checkpoint-store write access into code execution. Patch versions, strict msgpack settings and a 30-minute audit.

Read time
17 min
Word count
2.7K
Sections
13
FAQs
8
Share
Dark hero graphic titled LangGraph checkpointer RCE chain with four labelled security cards
The LangGraph checkpointer chain: SQL injection in filter keys, msgpack object reconstruction, and RediSearch query injection.
On this page · 13 sections
  1. What actually broke
  2. How the chain works
  3. Which deployments are actually exposed
  4. The 30-minute audit
  5. Hardening past the patch
  6. Two escape hatches that silently disable the fix
  7. Detection: what to look for in logs
  8. Why the "moderate" rating is misleading
  9. Where this fits in your agent threat model
  10. India-specific considerations
  11. FAQ
  12. How eCorpIT can help
  13. References

Summary. Three now-patched LangGraph flaws let an attacker walk from a metadata filter string to code execution on a self-hosted agent server. Check Point researcher Yarden Porat reported all three: CVE-2025-67644 (CVSS 7.3, SQL injection in the SQLite checkpointer), CVE-2026-28277 (CVSS 6.8, unsafe msgpack deserialization in LangGraph itself) and CVE-2026-27022 (CVSS 6.5, RediSearch query injection in the JavaScript Redis checkpointer). The first two chain. The Hacker News published the details on 12 June 2026; the msgpack advisory, GHSA-g48c-2wqr-h844, went to the GitHub Advisory Database on 5 March 2026 with CWE-502 and an EPSS score of 0.332%. Fixed versions are langgraph-checkpoint-sqlite 3.0.1, langgraph 1.0.10 and @langchain/langgraph-checkpoint-redis 1.0.2. LangChain's managed LangSmith Deployment is not affected.

The reason this matters more than the CVSS numbers suggest: Check Point's 2026 Cloud Security Report found 64% of organisations already have AI agents in pilot or production and 12% have granted those agents privileged access to core systems. An agent runtime holds LLM API keys, database credentials and conversation state. In India, personal data sitting in that state is squarely inside the Digital Personal Data Protection Act 2023, where the Data Protection Board can levy up to ₹250 crore (about $26 million) per major violation. A checkpoint table is not a cache. It is a credential-adjacent datastore that your application deserialises into live Python objects.

What actually broke

LangGraph persists agent state as checkpoints. Every superstep writes a serialised snapshot of the graph's channels to whatever backing store you configured, and get_state_history() reads them back so an agent can resume, branch or replay a thread. The three flaws sit at two different layers of that path: the query that finds a checkpoint, and the decoder that turns its bytes back into objects.

CVE-2025-67644: SQL injection through metadata filter keys

The SQLite checkpointer's _metadata_predicate() builds its WHERE clause with f-string interpolation. User-supplied metadata filter keys land directly in the SQL text, including inside json_extract expressions, with no parameterisation and no escaping. Any application that passes an untrusted filter dictionary into a checkpoint search hands the attacker query control. GitLab's advisory database records the affected range as langgraph-checkpoint-sqlite 3.0.0 and below, fixed in 3.0.1, carrying a CVSS score of 7.3 under GHSA-9rwj-6rc7-p77c.

On its own, this leaks. An attacker bypasses the thread filter and reads every checkpoint row in the table: other users' conversation state, thread identifiers, whatever metadata your graph writes. For a multi-tenant agent that is already a reportable incident.

CVE-2026-28277: msgpack deserialisation that rebuilds arbitrary Python objects

LangGraph's JsonPlusSerializer encodes checkpoints as msgpack, and its decoder handles extension types by reconstructing Python objects. The GitHub advisory describes the pattern as equivalent to getattr(importlib.import_module(module_name), callable_name)(arguments). Any importable callable, invoked with attacker-supplied arguments. That includes os.system and subprocess.Popen.

The advisory rates it Moderate at 6.8, with the vector CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H, and is explicit that it is a defence-in-depth issue: exploitation requires the ability to write attacker-controlled checkpoint bytes at rest. Affected versions are langgraph 1.0.9 and below; the fix shipped in 1.0.10 on 5 March 2026. LangGraph's own note says there is no evidence of exploitation in the wild.

CVE-2026-27022: RediSearch query injection in the JavaScript checkpointer

The RedisSaver and ShallowRedisSaver classes in @langchain/langgraph-checkpoint-redis interpolate user-provided filter keys and values straight into RediSearch queries. RediSearch treats characters like @, |, -, *, ( and ) as syntax, so an attacker who controls a filter value can rewrite the query logic and bypass the access controls that were supposed to scope results to one thread. It is CWE-74, CVSS 6.5, vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N, published to NVD on 20 February 2026 under GHSA-5mx2-w598-339m. The fix, in pull request 1943, adds an escapeRediSearchTagValue utility and also hardens the MongoDB checkpoint path by rejecting non-primitive filter values, which closes a parallel MongoDB operator-injection hole.

One version discrepancy worth knowing before you write a ticket. The Hacker News, citing the GitHub advisory, gives the affected range as versions before 1.0.1. SentinelOne's vulnerability database and the linked release tag both point at 1.0.2. Pin 1.0.2 or later and the argument goes away.

How the chain works

Read the second and third bullets slowly, because this is where a "requires privileged write access" advisory quietly stops requiring privileged write access.

  1. The attacker builds a msgpack payload whose extension type names a dangerous callable and its arguments.
  1. The attacker sends a malicious filter parameter to an endpoint that reaches get_state_history(), exploiting CVE-2025-67644 so the SQL query returns a fabricated checkpoint row whose checkpoint column contains that payload.
  1. The application processes the result set and deserialises the BLOB.
  1. CVE-2026-28277 reconstructs the attacker's object. The payload runs inside the agent runtime.

The attacker never needed write access to the database. The SQL injection manufactures the row inside the query result. That is the whole trick, and it is why triaging CVE-2026-28277 in isolation as "post-exploitation only" gets the priority wrong on any deployment that also runs an unpatched SQLite checkpointer with user-influenced filters.

Check Point's write-up puts the exposure boundary plainly: the chain is exploitable in self-hosted deployments using the SQLite or Redis checkpointer with user-controlled filter input, and LangChain's managed platform is not affected.

Which deployments are actually exposed

Most teams do not know which checkpointer their staging cluster is running, because it was chosen in week one of a prototype and never revisited. Start here.

Checkpointer backend Affected by Minimum safe version What to check first
langgraph-checkpoint-sqlite (Python) CVE-2025-67644 and CVE-2026-28277 3.0.1, plus langgraph 1.0.10 Whether any HTTP handler passes a request-derived dict into a checkpoint search
@langchain/langgraph-checkpoint-redis (JS) CVE-2026-27022 1.0.2 Filter values reaching RedisSaver or ShallowRedisSaver without escaping
MongoDB checkpoint (JS) Operator injection hardened in the same patch Ship with the 1.0.2 release train Filter values that are objects rather than primitives
PostgreSQL checkpointer Not named in these three advisories Current langgraph 1.0.10 Still patch langgraph itself for the msgpack decoder
In-memory / no persistence Not exposed via a store Current langgraph Nothing persists, but review any custom serializer hooks
LangSmith Deployment (managed) Not affected Managed by LangChain Confirm you are genuinely on the managed plane, not a self-hosted copy

The row that catches people is PostgreSQL. Teams read "SQLite and Redis" and close the ticket. The msgpack decoder lives in langgraph, not in the SQLite package, so a Postgres-backed deployment on langgraph 1.0.9 still deserialises checkpoints unsafely. It simply lacks the SQL injection that would let an unauthenticated caller forge a row. If your Postgres credentials leak, or a batch job with write access is compromised, the deserialisation path is right there.

The 30-minute audit

Run this against every environment that resumes agent state, including the staging cluster nobody owns. Each step is a single command and a pass criterion.

Step Command Pass criterion
1. Inventory Python packages `pip list \ grep -Ei "langgraph\ langchain"` langgraph at 1.0.10 or later
2. Inventory the SQLite checkpointer pip show langgraph-checkpoint-sqlite Version 3.0.1 or later, or the package is absent
3. Inventory the JS checkpointer npm list @langchain/langgraph-checkpoint-redis Version 1.0.2 or later, or the package is absent
4. Find untrusted filter paths `grep -rn "get_state_history\ aget_state_history" --include=*.py .` Every call site takes a server-constructed filter, never a raw request body
5. Check the JS filter paths `grep -rn "RedisSaver\ ShallowRedisSaver" --include=.ts --include=.js .` Filter values are escaped or allowlisted before the call
6. Confirm strict mode `env \ grep LANGGRAPH_STRICT_MSGPACK` Set to true in every production environment
7. Look for custom decoder hooks `grep -rn "ext_hook\ JsonPlusSerializer(" --include=*.py .` No custom ext_hook, or one with an explicit allowlist
8. Review store write access List IAM principals and service accounts with write on the checkpoint store Only the agent runtime and one break-glass role

Steps 4 and 5 are the ones that decide your severity. If no user-controlled string reaches a filter key, you have a patching task. If one does, and you are below the fixed versions, you have an incident-response task and the order of operations changes: contain first, rotate the credentials the runtime can reach, then patch.

Hardening past the patch

Upgrading closes the injection. It does not, by itself, stop the decoder from rebuilding arbitrary types, because the default policy after the patch is still permissive. LangGraph shipped an allowlist mechanism alongside the fix, and it has three states.

Setting for allowed_msgpack_modules Behaviour When to use it
True (default when strict mode is off) Reconstructs all extension types, logs a warning for unregistered ones Local development only
None (strict) Reconstructs only the built-in safe set, blocks everything else Production default, once you have read the warnings from a staging run
[(module, class_name), ...] Built-in safe set plus exactly the listed symbols, matched exactly Production, when strict mode breaks a legitimate custom type

Setting the environment variable LANGGRAPH_STRICT_MSGPACK to a truthy value (1, true or yes) flips JsonPlusSerializer() to default allowed_msgpack_modules to None instead of True, unless you passed the argument explicitly.

The built-in safe set covers what most graphs actually persist: datetime types, uuid.UUID, decimal.Decimal, set, frozenset, deque, ipaddress types, pathlib paths, zoneinfo.ZoneInfo, compiled regular expressions and selected LangGraph internal types. When strict mode is on and you compile a StateGraph, LangGraph walks your state, input, output and context schemas plus node and branch input schemas and channel value types, and derives an allowlist automatically. It picks up Pydantic v1 and v2 models, dataclasses, enums, TypedDict field types and common typing constructs, plus a curated set of LangChain message classes.


            # Patch the Python side
pip install --upgrade "langgraph>=1.0.10" "langgraph-checkpoint-sqlite>=3.0.1"

# Patch the JavaScript side
npm install @langchain/langgraph-checkpoint-redis@^1.0.2
npm list @langchain/langgraph-checkpoint-redis

# Turn on strict deserialisation in every non-local environment
export LANGGRAPH_STRICT_MSGPACK=true
          

Roll strict mode out in staging first and read the logs. The permissive default warns on every unregistered extension type it reconstructs, which gives you a free inventory of exactly what your graphs serialise before you start blocking anything.

Two escape hatches that silently disable the fix

Both are documented in the advisory, and both are easy to hit by accident.

The first: allowlist enforcement is applied by the checkpointer, through a with_allowlist(...) method. A checkpointer implementation that does not provide it skips enforcement and emits a warning. If you wrote your own saver, or you are using a community backend, strict mode may be doing nothing at all. Verify rather than assume.

The second: if your application supplies a custom msgpack unpack hook via ext_hook, that hook controls reconstruction and bypasses the default allowlist checks entirely. The advisory calls this an intentional escape hatch. It is also exactly the kind of code somebody adds to make one stubborn type round-trip, three sprints before the audit.

A third failure mode is not in the advisory but shows up in practice: constructing serializers or checkpointers manually rather than letting StateGraph.compile() wire them up. The derived allowlist only applies when LangGraph compiles the graph and the checkpointer supports propagation. Hand-built object graphs get the default policy.

Detection: what to look for in logs

You cannot retroactively prove nothing happened, but you can look in three places.

For the SQLite path, search application logs for filter keys containing SQL metacharacters, quotes, json_extract, UNION or comment markers, and for checkpoint searches that returned unusually large result sets. For the Redis path, look for filter values containing RediSearch syntax characters (@, |, -, *, (, ), {, }, [, ], backslash) and enable verbose Redis query logging so the executed queries are actually recoverable. Redis slow-query logs are useful here because injected queries tend to be structurally odd.

For the deserialisation path, the permissive default's own warnings are the signal. Every reconstruction of an unregistered extension type gets logged. If you have those logs from before the patch, grep them for module names that are not in your application's dependency tree.

At the infrastructure layer, treat the checkpoint store as integrity-sensitive. Restrict write access to the runtime itself, rotate credentials if compromise is suspected, and log every principal that has ever written to it. This is the same posture we argue for in enterprise AI agent governance layers: the agent's blast radius is the union of everything its credentials can reach, and the checkpoint store is inside that union.

Why the "moderate" rating is misleading

CVE-2026-28277 scores 6.8 with an EPSS probability of 0.332%, which sits at the 56th percentile. Read alone, that is a patch-next-cycle number. Read as the second half of a chain that starts with a 7.3 SQL injection reachable from an HTTP parameter, it is not.

This is a recurring pattern with agent frameworks rather than a LangGraph-specific failure. Check Point's conclusion was that classic vulnerability classes become more potent inside AI agent frameworks because those frameworks carry elevated access and trust. The framework holds provider API keys, database handles and tool credentials in one process. A bug class that would be a data-leak in a CRUD service becomes credential exfiltration in an agent runtime.

Lotem Finkelstein, VP, Check Point Research, framed the broader shift in the firm's AI Security Report 2026: "The expertise barrier that separated capable attackers from the rest is disappearing, and defenders can no longer assume a human is setting the pace on the other side. The organizations that stay ahead will be the ones that govern how AI is used, secure the AI systems they now depend on, and defend at machine speed rather than human speed."

The same report found that between October 2025 and May 2026, 87% to 93% of organisations experienced at least one high-risk AI interaction every month. Check Point's 2026 Cloud Security Report puts the governance gap in one figure: 77% of organisations have updated their cloud security strategy in response to AI, but only 26% say they have the architecture to enforce it, a 51-point spread between intent and capability.

Check Point's own remediation guidance for this chain goes past the version bump: put authentication in front of self-hosted LangGraph servers, avoid long-lived static secrets, enforce network segmentation, treat AI agents as privileged identities, and apply least privilege to the agent's access footprint. That last point is the durable one. The framework you pick matters less than the credentials you hand it, which is the argument we made when comparing AI agent frameworks for production.

Where this fits in your agent threat model

Prompt injection gets the attention because it is novel. This chain is a reminder that the boring half of the attack surface is still there: an ORM-free f-string, a permissive deserialiser, an endpoint that trusts a dictionary from the client. Teams that have invested in prompt injection guardrails for AI agents sometimes have zero coverage on the persistence layer beneath them, and an attacker with a choice will take the SQL injection every time.

Three practical adjustments follow.

Treat the checkpoint store as a trust boundary, not an implementation detail. Anything that can write to it can, in the worst case, execute in your runtime. That deserves the same review as a message queue an untrusted producer can publish to.

Make filter construction server-side by contract. The agent server should build filter dictionaries from a validated session, never accept one from a request body. This single rule would have neutralised two of the three CVEs regardless of version.

Pin and monitor the framework, not just the model. Model versions get change-managed carefully while langgraph floats on a caret range. The same discipline that applies to MCP server hardening applies here: agent-adjacent infrastructure needs a named owner and a patch SLA.

India-specific considerations

For Indian teams, the compliance exposure is concrete rather than theoretical. Agent checkpoint state routinely contains names, contact details, order histories and support transcripts, all of which are personal data under the Digital Personal Data Protection Act 2023. The Act's substantive obligations tighten through 2026 ahead of hard enforcement in May 2027, and the Data Protection Board of India can impose penalties reaching ₹250 crore, roughly $26 million, for major violations.

Two consequences follow for anyone running a self-hosted agent on Indian customer data. First, a checkpoint-table leak through CVE-2025-67644 is a personal-data breach, not just a bug, and your breach-notification clock is a legal one. Second, retention limits apply to checkpoints. Most teams never set a TTL on the checkpoint table, so a graph that ran once in March is still holding a full conversation transcript in August. Set retention, and document it, alongside the rest of the work in the DPDP Act engineering playbook.

The practical sequencing for an Indian engineering team is patch, then scope, then retain. Get to the fixed versions this week. Then determine whether any user-controlled string ever reached a filter key, because that answer decides whether you are writing a changelog entry or a breach assessment. Then put a retention policy on the store so the next incident has a smaller blast radius. For the wider picture of what production agents need before they touch customer data, see our guide to enterprise AI agents in production.

FAQ

How eCorpIT can help

eCorpIT builds and hardens production AI agent systems for teams in India and abroad, and this is exactly the kind of work our senior engineering teams do: inventory the framework and checkpointer versions across every environment, trace which request paths reach a filter key, turn on strict deserialisation without breaking your graphs, and put retention and least-privilege controls on the state store. We are ISO 27001:2022 certified and CMMI Level 5 appraised, and we design applications aligned with DPDP requirements. If you are running self-hosted LangGraph and want a second pair of eyes on the persistence layer before your next audit, contact us and we will scope a review.

References

  1. LangGraph Flaw Chain Exposes Self-Hosted AI Agents to Remote Code Execution - The Hacker News, 12 June 2026
  1. CVE-2026-28277: LangGraph checkpoint loading has unsafe msgpack deserialization (GHSA-g48c-2wqr-h844) - GitHub Advisory Database, 5 March 2026
  1. GHSA-9rwj-6rc7-p77c: LangGraph SQLite checkpointer SQL injection - langchain-ai/langgraph security advisories
  1. GHSA-5mx2-w598-339m: RediSearch query injection in @langchain/langgraph-checkpoint-redis - langchain-ai/langgraphjs security advisories
  1. CVE-2025-67644 advisory for langgraph-checkpoint-sqlite - GitLab Advisory Database
  1. From SQLi to RCE: exploiting LangGraph's checkpointer - Check Point Research, 2026
  1. CVE-2026-27022: LangGraph Redis checkpoint query injection - SentinelOne Vulnerability Database, 27 February 2026
  1. Pull request 1943: escape RediSearch tag values in the Redis checkpointer - langchain-ai/langgraphjs
  1. NVD entry for CVE-2026-28277 - National Vulnerability Database
  1. CWE-502: Deserialization of Untrusted Data - MITRE
  1. AI used to help plan the break-in, now it's doing the break-in - Help Net Security, 15 July 2026
  1. AI adoption creates critical cloud security gaps for enterprises - Check Point Software press release, 2026
  1. India's DPDP timeline: critical compliance deadlines for 2026-27 - India Briefing, 11 May 2026
  1. Check Point's 2026 Cloud Security Report: Securing the AI Transformation - Unite.AI summary of the Check Point and Cybersecurity Insiders survey, 26 May 2026

Last updated: 5 August 2026.

Frequently asked

Quick answers.

01 Which LangGraph versions fix these three CVEs?
Upgrade langgraph to 1.0.10 or later for the msgpack deserialisation issue, langgraph-checkpoint-sqlite to 3.0.1 or later for the SQL injection, and @langchain/langgraph-checkpoint-redis to 1.0.2 or later for the RediSearch query injection. Patch all three even if you believe only one backend is in use, because staging environments frequently differ from production.
02 Is a PostgreSQL checkpointer safe from this chain?
PostgreSQL is not named in the three advisories, so it avoids the SQL injection and the RediSearch injection. It does not avoid CVE-2026-28277, because the unsafe msgpack decoder lives in the langgraph package itself. Any deployment running version 1.0.9 or below still reconstructs Python objects from checkpoint bytes and needs the upgrade.
03 Does upgrading alone stop arbitrary object reconstruction?
No. After patching, the default allowed_msgpack_modules value is still True, which reconstructs every extension type and only logs a warning. Set the environment variable LANGGRAPH_STRICT_MSGPACK to true so the serializer defaults to strict, or pass an explicit allowlist. Test in staging first and read the warning logs.
04 How was the attack chain actually executed?
The attacker crafts a msgpack payload, then sends a malicious filter parameter to an endpoint reaching get_state_history(). The SQL injection makes the query return a fabricated checkpoint row containing that payload. The application deserialises the row's BLOB, the unsafe decoder reconstructs the attacker's object, and code executes inside the agent runtime.
05 Is LangSmith Deployment affected by these vulnerabilities?
No. Check Point stated that LangChain's managed platform, LangSmith Deployment, is not affected, and the LangGraph maintainers said typical hosted configurations are designed to prevent the checkpoint-store tampering the threat model requires. The chain is exploitable in self-hosted deployments using the SQLite or Redis checkpointer with user-controlled filter input.
06 What can silently disable the msgpack allowlist?
Two documented escape hatches. A checkpointer that does not implement with_allowlist skips enforcement and only emits a warning, so custom or community savers may gain nothing from strict mode. Separately, an application-supplied ext_hook takes control of reconstruction and bypasses the default allowlist checks entirely, which is intentional but weakens the protection.
07 Were these flaws exploited in the wild?
The GitHub advisory for CVE-2026-28277 states there is no evidence of exploitation in the wild, and LangGraph is not aware of a practical exploitation path in existing deployments today. The EPSS score of 0.332% sits at the 56th percentile. Treat that as a reason to patch calmly, not as a reason to defer.
08 Does a checkpoint-table leak count as a breach under DPDP?
If the checkpoint state contains personal data, and agent conversation state usually does, then unauthorised access to it is a personal-data breach under the Digital Personal Data Protection Act 2023. The Data Protection Board of India can impose penalties up to ₹250 crore for major violations, so scope the exposure before deciding it was only a bug.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.