LangChain Core Serialization Injection (LangGrinch)
- Product
- LangChain langchain-core
- CVE
- CVE-2025-68664
- Disclosed
- 2025-12-23
- CVSS
- 9.3
- Auth
- pre-auth
- CISA KEV
- no
- Affected
- langchain-core < 0.3.81 and >= 1.0.0, < 1.2.5
- Fixed
- 0.3.81, 1.2.5
Summary
Reported by Yarden Porat and nicknamed LangGrinch, this flaw let attacker-controlled data masquerade as trusted LangChain objects when serialized and loaded again. It can leak environment secrets and instantiate LangChain classes with attacker parameters. Not strictly RCE by itself, but a critical primitive in agent pipelines that persist or stream LLM output.
Root cause
dumps()/dumpd() did not escape free-form dictionaries containing the reserved 'lc' key that marks serialized LangChain objects. Data such as LLM-produced metadata or additional_kwargs could therefore embed {'lc': 1, 'type': 'secret', ...} or constructor payloads that load() later treated as trusted. With secrets_from_env=True (the old default) this resolved environment secrets; constructor payloads could instantiate Serializable classes in trusted namespaces (e.g. Jinja2-backed prompt templates, which the fix now blocks by default).
Impact
Exfiltration of API keys from the environment and attacker-controlled object instantiation, potentially leading to code execution.
Public PoC
attacker_dict = {
"user_data": {
"lc": 1,
"type": "secret",
"id": ["OPENAI_API_KEY"]
}
}
serialized = dumps(attacker_dict) # Bug: does NOT escape the 'lc' key
loads(serialized) # resolves the env secretSource: GHSA-c67j-w6g6-q2cm
Detection
Audit for langchain-core versions below the fixed releases and for load()/loads() on data that originated from users or LLM output; search stored payloads for '"lc": 1' with type 'secret'.
Mitigation
Upgrade langchain-core, disable secrets_from_env, and only deserialize data you produced.