Breach report
The LangChain eval-and-fetch class: how load_prompt, VectorSQLDatabaseChain, and SitemapLoader became RCE and SSRF
What happened
LangChain is one of the most widely used frameworks for building LLM applications. Across 2023 and 2024 several of its components shipped the same underlying mistake: they handed untrusted strings to code that evaluated or fetched them.
- CVE-2023-34541 — the
load_promptfunction allowed arbitrary Python code execution. Any application loading an attacker-influenced prompt file could be made to run arbitrary code. Fixed in LangChain0.0.247(published June 20, 2023); rated Critical, CVSS 9.3. - CVE-2024-21513 —
VectorSQLDatabaseChainin langchain-experimental calledevalon values returned from the database. An attacker who could influence the input prompt while this chain was configured achieved arbitrary Python execution. Affected0.0.15through0.0.20, fixed in0.0.21; disclosed June 19, 2024, CVSS 7.3. - CVE-2023-46229 — the
SitemapLoaderplaced no scope restriction on the URLs it fetched, so a supplied sitemap could point at intranet resources, giving server-side request forgery against internal APIs. Fixed in0.0.317(October 13, 2023).
Root cause
Untrusted, often model-influenced, data was treated as trusted code or trusted destinations. load_prompt and VectorSQLDatabaseChain fed attacker-shaped strings into evaluation (CWE-94 code injection); the sitemap loader fetched whatever URL it was given with no allowlist (CWE-918 SSRF). Because prompts and retrieved values are attacker-influenceable, this is OWASP LLM05 Improper Output Handling triggered by LLM01 Prompt Injection.
How it would have been caught
Static analysis flagging eval/exec on data that flows from prompts, DB rows, or files would have caught the RCE variants at the source. An SSRF test that hands the sitemap loader a URL pointing at 169.254.169.254 or an internal host, asserting the request is blocked, would have caught the loader flaw. Software Composition Analysis catches all three by version.
How to prevent it
- Upgrade past the fixed versions: LangChain
0.0.247/0.0.317, langchain-experimental0.0.21. - Never
eval/execprompt-, database-, or file-derived strings; use parameterized queries and safe parsers. - Enforce an egress allowlist on any URL fetcher and deny requests to private/link-local ranges.
- Run agent tools under least privilege in an egress-jailed sandbox.
The Breachwire test (red → green)
For each variant, drive the real vector: a prompt file / DB value carrying a Python payload, and a sitemap naming an internal host. Confirm code executes and the internal request fires on the vulnerable versions (RED). Upgrade, remove the eval, and apply the egress allowlist, then confirm the payloads are inert and the internal fetch is blocked — while a benign prompt load, query, and public-sitemap crawl still succeed.