Home/CVEs/CVE-2025-68665
HIGH 8.6CWE-502 Exploit Verified

CVE-2025-68665: Environment Variable Exfiltration via Deserialization in @langchain/core load() Function

Published 2025-12-23·@langchain/core <0.3.80·Fixed in 0.3.80

CVE-2025-68665 is a critical deserialization vulnerability in the @langchain/core npm package (versions prior to 0.3.80) that allows unauthenticated attackers to exfiltrate arbitrary environment variables — including API keys, database passwords, and cloud credentials — by injecting crafted JSON payloads into endpoints that use the load() function. With a CVSS score of 8.6 and network-accessible attack surface requiring no authentication, this vulnerability poses an immediate risk to any application exposing LangChain deserialization endpoints.

Exploitation Flow

7 steps · verified against live environment
1 / 7context
The Vulnerability
@langchain/core <0.3.80
The load() function assumed that serialized data containing 'lc' keys was always from a trusted LangChain serialization source, not user-controlled input, and secretsFromEnv effectively defaulted to true.
@langchain/core<0.3.80Fixed: 0.3.80
Vulnerable function: load()
The load() function assumed that serialized data containing 'lc' keys was always from a trusted LangChain serialization source, not user-controlled input.
Hands-On Lab Available
Docker-based exploit lab with step-by-step walkthrough · 5 secrets to extract · Zeek network captures included

Overview

CVE-2025-68665 is a deserialization vulnerability in the @langchain/core npm package affecting all versions prior to 0.3.80. The vulnerability resides in the load() function, imported via @langchain/core/load, which is responsible for deserializing LangChain serialized objects from JSON.

The core issue is that the deserializer fails to distinguish between legitimate internal LangChain serialized structures and attacker-controlled injection payloads, allowing an unauthenticated remote attacker to extract sensitive environment variables from the server process. The load() function treats any JSON object containing an lc key as a legitimate LangChain serialized structure, and when the type field is set to "secret", it resolves the reference against process.env and returns the plaintext value.

This is classified under CWE-502 (Deserialization of Untrusted Data) and carries a CVSS 3.1 score of 8.6 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N), reflecting the network-accessible, unauthenticated, and high-confidentiality-impact nature of the attack.

Technical Analysis

The root cause lies in the interaction between the toJSON() serialization method and the load() deserialization function. During serialization, toJSON() does not escape or sanitize objects that contain lc keys within free-form kwargs fields.

When user-controlled data containing the structure {"lc": 1, "type": "secret", "id": ["VARIABLE_NAME"]} is deserialized, the load() function interprets it as a first-class LangChain secret reference and looks up the environment variable value from process.env. No authentication or special headers are required — the attacker only needs to send a JSON payload with Content-Type: application/json.

The attack is trivially repeatable: by changing the value in the id array, the attacker can enumerate and extract any environment variable. In our verified exploitation, each probe returned an HTTP 200 with the secret value in approximately 3-4ms, indistinguishable from normal application traffic by response time alone.

The contrast with benign requests is instructive: a POST to the same endpoint with normal data returns the input echoed back without any environment variable resolution. The presence of the lc key is the sole trigger that activates the secret resolution codepath, making this a precise and reliable exploitation vector.

Impact Assessment

Any application that exposes a LangChain deserialization endpoint is vulnerable to full environment variable exfiltration by unauthenticated remote attackers. A single attacker can systematically extract cloud provider credentials (AWS_SECRET_ACCESS_KEY), payment processing keys (STRIPE_SECRET_KEY), database credentials (DATABASE_PASSWORD), authentication secrets (JWT_SECRET), and AI service API keys (OPENAI_API_KEY).

The CVSS vector's Scope change (S:C) reflects that the compromised secrets can be used to attack systems beyond the vulnerable application itself — for instance, using leaked AWS credentials to access cloud infrastructure or using Stripe keys to perform fraudulent transactions.

The vulnerability requires no prerequisites beyond network access to the affected endpoint. Given the widespread adoption of LangChain in AI/ML application stacks and the common practice of storing sensitive credentials in environment variables, the blast radius extends to cloud infrastructure, databases, third-party SaaS integrations, and authentication systems.

Detection & Monitoring

Detection should focus on inspecting HTTP request bodies for the characteristic LangChain secret reference structure. The primary indicators are JSON payloads containing "lc":1 combined with "type":"secret" in POST requests to endpoints that invoke the load() function.

In our observed attack traffic, all exploit requests were POST requests with Content-Type: application/json and a Python-urllib/3.10 user agent, though the user agent is trivially spoofable. The Zeek HTTP logs show these requests as text/json content type with request body lengths between 48 and 56 bytes, returning 200 OK responses — making them blend in with legitimate traffic at the network metadata level.

For application-layer detection, WAF rules should inspect JSON request bodies for the co-occurrence of "lc" as a top-level key, "type":"secret", and an "id" array. Response-side detection is also effective: monitor for responses containing patterns matching known secret formats (strings beginning with sk-, sk_live_, or matching AWS key patterns) from deserialization endpoints.