Breachwire.riscent

Breach report

The LangChain eval-and-fetch class: how load_prompt, VectorSQLDatabaseChain, and SitemapLoader became RCE and SSRF

AI & LLM BreachesCritical (RCE) / High (SSRF)CVE-2023-34541, CVE-2024-21513, CVE-2023-462292023-07
The bottom lineA recurring LangChain pattern — evaluating untrusted strings and fetching attacker-named URLs — produced remote code execution via load_prompt and VectorSQLDatabaseChain and server-side request forgery via the sitemap loader.
Category
AI & LLM Breaches
Type
Vulnerability class · Multiple CVEs (LangChain)
Date
2023-07
Severity
Critical (RCE) / High (SSRF)
OWASP
LLM05 Improper Output Handling; LLM01 Prompt Injection
CWE / CVE
CWE-94; CWE-918 CVE-2023-34541, CVE-2024-21513, CVE-2023-46229

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_prompt function allowed arbitrary Python code execution. Any application loading an attacker-influenced prompt file could be made to run arbitrary code. Fixed in LangChain 0.0.247 (published June 20, 2023); rated Critical, CVSS 9.3.
  • CVE-2024-21513VectorSQLDatabaseChain in langchain-experimental called eval on values returned from the database. An attacker who could influence the input prompt while this chain was configured achieved arbitrary Python execution. Affected 0.0.15 through 0.0.20, fixed in 0.0.21; disclosed June 19, 2024, CVSS 7.3.
  • CVE-2023-46229 — the SitemapLoader placed 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 in 0.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-experimental 0.0.21.
  • Never eval/exec prompt-, 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.