The Vulnerability That Hid in Your AI Observability Layer
When teams add LangSmith to their LLM applications for tracing and observability, they're adding middleware that sits directly in the request path. That's a privileged position — and in LangSmith SDK versions prior to 0.8.18, it turned out to be an exploitable one.
Security advisory GHSA-f4xh-w4cj-qxq8 describes a high-severity arbitrary server-side file read in LangSmith SDK's TracingMiddleware. The vulnerability meant that a crafted request could cause the middleware to read files from the server's local filesystem — files the requester was never meant to see. This post walks through what went wrong, how it was fixed, and what Python developers building on LangChain/LangSmith should understand about middleware-level security.
The Vulnerability Explained
What Is TracingMiddleware Doing?
LangSmith's TracingMiddleware is an ASGI/WSGI-compatible middleware layer that intercepts HTTP requests to log traces of LLM interactions. Because it processes incoming request data — headers, body content, route parameters — before passing control downstream, it handles attacker-influenced input very early in the request lifecycle.
The vulnerability is a path traversal / arbitrary file read (CWE-22). In the affected versions (≤ 0.8.15), the middleware processed certain input values and used them — directly or indirectly — in file operations without adequately restricting the resulting filesystem path.
The Classic Path Traversal Pattern
A path traversal vulnerability typically looks like this in Python:
# VULNERABLE — user-controlled value used directly in file open
def read_trace_artifact(artifact_name: str) -> str:
base_dir = "/app/traces"
path = os.path.join(base_dir, artifact_name) # ← no canonicalization
with open(path, "r") as f:
return f.read()
If artifact_name is ../../../../etc/passwd, os.path.join produces /etc/passwd — completely outside /app/traces. Without a check that the resolved path still starts with the intended base directory, the application reads any file the server process can access.
In LangSmith's case, the TracingMiddleware component was the entry point where tainted request data could reach such file-read logic.
Real-World Impact for LangSmith Users
Applications using LangSmith for tracing are often:
- Deployed in cloud environments with secrets mounted as files (e.g.,
/run/secrets/db_password, Kubernetes secret volumes) - Running alongside
.envfiles containing API keys and database credentials - Hosting model weight files or proprietary prompt templates on the local filesystem
An attacker exploiting this vulnerability against a production LangSmith-instrumented application could potentially exfiltrate any of these resources by sending a crafted tracing request. Because TracingMiddleware is designed to receive external HTTP traffic, the attack surface is directly internet-exposed in many deployments.
The Fix
Upgrading from 0.8.15 to 0.8.18
The remediation is a targeted version upgrade. The poetry.lock diff shows the transition:
Before (vulnerable):
# poetry.lock — langsmith pinned at 0.8.15
name = "langsmith"
version = "0.8.15"
After (fixed):
# poetry.lock — langsmith upgraded to 0.8.18
name = "langsmith"
version = "0.8.18"
LangSmith 0.8.18 patches the TracingMiddleware to sanitize path-like values before they can reach any file-open operation. The fix in the upstream SDK ensures that user-influenced input is validated against an allowlist or canonicalized and checked against a restricted base path — preventing traversal sequences like ../ from escaping the intended directory.
What Else Changed in the Lock File?
The poetry.lock diff also reveals that several previously optional dependencies — asyncpg, backoff, boto3, botocore — were promoted from optional = true to optional = false. This reflects LangSmith 0.8.18 making these dependencies unconditional (likely because features requiring them are now always enabled). The markers = "extra == \"postgres\"" and markers = "extra == \"langfuse\"" guards were removed accordingly.
name = "asyncpg"
version = "0.31.0"
-optional = true
+optional = false
python-versions = ">=3.9.0"
groups = ["main"]
-markers = "extra == \"postgres\""
This is a packaging change, not a security change — but it's worth noting if your deployment environment has restrictions on which packages can be installed.
Why This Fix Is Sufficient
Because the vulnerability lives entirely within the LangSmith SDK's own middleware code (not in your application code), upgrading the package is a complete fix. Your application does not need to add its own path sanitization on top — though defense-in-depth is always worthwhile.
Key Takeaways
TracingMiddlewarein LangSmith ≤ 0.8.15 processed request data without sufficient path sanitization, creating a direct path from attacker input to server filesystem reads.- AI observability libraries deserve the same security scrutiny as any other web middleware — they sit in the request path and handle raw, potentially hostile input.
- The
poetry.lockfile is your ground truth for what's actually installed; pinning to 0.8.15 while a patched 0.8.18 exists left this vulnerability open unnecessarily. - Trivy's GHSA-f4xh-w4cj-qxq8 rule can detect this specific vulnerable version range in your dependency lock files — integrate it into CI to catch regressions.
- Upgrading to 0.8.18 is the complete fix — no application-level code changes are required because the vulnerability is entirely within the SDK's middleware.
How Orbis AppSec Detected This
- Source: Attacker-controlled HTTP request data (headers, body, or route parameters) processed by
TracingMiddlewarein the LangSmith SDK - Sink: File-read operations within
TracingMiddlewarethat consumed path values derived from request input without adequate sanitization - Missing control: No path canonicalization or base-directory enforcement before the file-open call, allowing
../traversal sequences to escape the intended directory scope - CWE: CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
- Fix: Upgraded
langsmithfrom0.8.15to0.8.18inpoetry.lockandpyproject.toml, replacing the vulnerableTracingMiddlewareimplementation with the patched version from the upstream SDK
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
GHSA-f4xh-w4cj-qxq8 is a sharp reminder that the observability and tracing layers we bolt onto AI applications aren't exempt from classic web security vulnerabilities. An arbitrary file read in TracingMiddleware could expose secrets, configuration files, or sensitive data to any attacker who can send a crafted HTTP request — a low bar in any internet-facing deployment.
The fix is straightforward: upgrade LangSmith to 0.8.18. But the broader lesson is architectural — middleware that processes unauthenticated request data and performs file I/O is a high-risk combination that deserves careful review, regardless of the vendor or framework. Build dependency scanning into your CI pipeline, subscribe to advisories for your AI/ML dependencies, and apply filesystem least-privilege so that even if a traversal bug slips through, its impact is contained.