High

LangChain load_chain Path Traversal Exploitation

LangChain's load_chain() function is supposed to only pull chain, prompt, and agent configurations from a trusted GitHub repository. A flaw in versions 0.1.10 and earlier lets an attacker sneak a '../' sequence (or its URL-encoded variants) into the path, escaping that trusted location and fetching whatever file or config they want instead.

How the attack works

An attacker sends a chain/config-load request containing a directory traversal sequence, either in plain form or URL/double-URL encoded, so it escapes the intended repository prefix. From a Python-based process this can be used two ways: to read arbitrary local files such as ones holding API keys, or to load an attacker-controlled chain configuration that executes arbitrary code when LangChain processes it. The detection logic ties the traversal request to the exact process that made it, then follows everything that process and its descendants do afterward. If, in that same session and time window, a secret-bearing file gets read, the two events are linked as a single escalation from traversal to credential theft.

Netzilo detection

Netzilo reports this behaviour when it is observed.

Signature ID
b7c41d2e-5a83-4f16-9c2d-8e17a6f04b39
Severity
High

Why it matters

Successful exploitation exposes API keys and other secrets, or lets an attacker substitute a malicious chain/agent configuration that runs arbitrary code inside the LangChain application.

What you can do

  • Upgrade LangChain past 0.1.10 or apply the vendor's fix for CVE-2024-28088.
  • Restrict load_chain() and similar loaders to a strict allow-list of trusted hub paths, rejecting any path containing '../' or its encoded forms.
  • Audit where secrets (API keys, credentials) are stored relative to the application's working directory and file permissions.
  • Review logs for chain/config-load requests containing traversal sequences followed by reads of sensitive files in the same session, and treat repeated occurrences outside of known testing as suspicious.

Known benign look-alikes

  • Security testing of a LangChain deployment - pentest, CVE validation or a regression test that deliberately passes ../ into load_chain. Expected to fire.
  • A self-hosted or mirrored prompt hub addressed with a relative path ("../shared/chain.json") by an internal loader. The traversal token is real, so the report is accurate; triage by looking at the resolved host in the chain.
  • A signed URL, base64 blob or opaque token in a query string that happens to contain the literal %2e%2e byte sequence. Mitigated by requiring a chain/config load context in the URL or a Python-family process in the resolved lineage, and by only reporting.
  • Startup .env or credentials.json reads by the same Python service. This is why the credential read is an escalation stage only and can never fire on its own - the traversal request is a required anchor.
  • Notebook or CLI experimentation where a data scientist loads a local chain config over a local HTTP file server using a relative path.

References