← Back to Research

The RAG Chatbot Bug That Turns a URL Paste Into Remote Code Execution (CVE-2026-15330)

CVE-2026-15330 — CVSS 9.1. Affects langchain-community 0.3.0 through 0.3.14 with UnstructuredURLLoader and disk-backed caching enabled. Every "paste a URL, I'll summarize it" chatbot shipped in 2025 opened a door most teams didn't realize they had installed.

Every "paste a URL, I'll summarize it" chatbot shipped in 2025 opened a door most teams didn't realize they had installed. LangChain's UnstructuredURLLoader cached fetched bytes via Python pickle, keyed on URL hash. Pickle plus attacker-controlled input is always the same answer. CVE-2026-15330.

What the bug is

The vulnerability class is SSRF chained to pickle-deserialization RCE. Affected versions are langchain-community 0.3.0 through 0.3.14 running UnstructuredURLLoader with the disk-backed cache flag set — which is the copy-paste example from roughly half the "build your own RAG" tutorials published between Q2 2024 and Q1 2026.

The cache directory stored each fetched document as a pickled Python object named by the SHA-256 of the requested URL. Any code path that later read the cache rehydrated the pickle without a signature check. CVSS 9.1. Unauthenticated attacker, network vector, low complexity, full compromise.

How the attack works

The chain is four steps and it runs in seconds.

  1. Attacker pastes a URL they control into the chatbot ("summarize this article for me please").
  2. The LangChain backend fetches the URL and stores the response bytes as a pickle at cache/<sha256-of-url>.pkl.
  3. Attacker re-requests the same URL a few seconds later. The loader hits the cache first and deserializes the pickled bytes before anything else runs.
  4. The attacker-authored __reduce__ inside the pickle fires. RCE inside the chatbot backend, with whatever credentials the service holds — which on a typical RAG stack includes the vector database, the API keys for the embedding provider, and the document corpus.

The one-line version of the vulnerable code:

# VULNERABLE -- loads attacker-controlled pickle from cache
with open(cache_path, "rb") as f:
    doc = pickle.load(f)  # <-- RCE here

Why your RAG chatbot probably has this

LangChain's default deploy pattern for the "chat with a URL" feature imports UnstructuredURLLoader and enables the cache with a single kwarg, because refetching the same URL on every message is wasteful. The cache is on by default in the LangServe templates shipped through January 2026. If your team stood up a API-backed chatbot using a tutorial from the last eighteen months, you almost certainly inherited this configuration.

The one flag that disables it is cache_dir=None on the loader. Most teams never touched it.

The fix

Upgrade to 0.3.15 or later. The 0.3.15 release migrated the cache format from pickle to msgpack, which cannot execute code on deserialization. The exact pip command:

pip install --upgrade "langchain-community>=0.3.15"

If you cannot upgrade immediately, disable the disk cache as a stopgap:

# Before (vulnerable)
loader = UnstructuredURLLoader(
    urls=[user_url],
    cache_dir="/var/cache/langchain",
)

# After (safe, no cache)
loader = UnstructuredURLLoader(
    urls=[user_url],
    cache_dir=None,
)

Then wipe the existing cache directory. Any pickled bytes sitting there from before the patch are poisoned by definition if an attacker has ever interacted with your chatbot.

How Celvex Sentry would have caught this

Offensive Simulation fingerprints LangChain response headers and probes the URL-loader endpoint pattern — the telltale timing signature where a second request for the same URL returns in a fraction of the first request's latency exposes a disk cache. When the fingerprint matches a vulnerable version, Supply Chain Integrity flags the pinned version in the SBOM scan and raises it to Critical because the chain to RCE is one attacker-controlled URL paste away.

Pen-testers hand you a PDF once a year; Celvex Sentry runs every attack they would, every week, and proves the ones that still work — with a fix attached.

Sources

Get your exposure check — full report in 4-24 hours

Full report in 4-24 hours. Real assessment on production-grade infrastructure. Paying customers get priority capacity.

Queue My Assessment