Skip to main content
CVE Vulnerability Database

CVE-2024-0243: Langchain RecursiveUrlLoader SSRF Vulnerability

CVE-2024-0243 is an SSRF vulnerability in Langchain's RecursiveUrlLoader that allows attackers to bypass prevent_outside restrictions and download external files. This article covers technical details, affected versions, and patches.

Published:

CVE-2024-0243 Overview

CVE-2024-0243 affects the RecursiveUrlLoader component in LangChain, a popular Python framework for building LLM-powered applications. The document loader fails to correctly enforce the prevent_outside=True boundary control when crawling links from a starting URL. An attacker who controls the content of a crawled page can inject links to arbitrary external hosts, and the loader will fetch that off-domain content into the application's document pipeline. The flaw is tracked as a Server-Side Request Forgery (SSRF) issue [CWE-918]. The vulnerability was resolved in langchain pull request #15559.

Critical Impact

Attackers controlling any crawled page can force LangChain applications to fetch attacker-chosen URLs, exposing internal services, cloud metadata endpoints, and sensitive content to the LLM pipeline.

Affected Products

  • LangChain (langchain-community) RecursiveUrlLoader
  • Versions prior to the patch merged in PR #15559
  • Applications embedding LangChain document loaders for retrieval-augmented generation (RAG)

Discovery Timeline

  • 2024-02-26 - CVE-2024-0243 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2024-0243

Vulnerability Analysis

The RecursiveUrlLoader accepts a prevent_outside flag intended to keep crawling within the initial base URL. The link extraction routine in langchain_community/document_loaders/recursive_url_loader.py compares candidate URLs to the base using a plain path.startswith(base_url) check. This string prefix comparison is insufficient to enforce a domain boundary. An attacker who controls the HTML at the seed URL can embed absolute links pointing to arbitrary hosts. Because the loader normalizes and enqueues those links regardless of scheme or hostname, the crawler proceeds to fetch attacker-controlled or internal endpoints. Retrieved content is then passed downstream into the RAG pipeline or LLM prompt context.

Root Cause

The defect is an incomplete URL origin check. The code trusted a lexical prefix match rather than parsing the URL and comparing scheme, host, and port against the base. Combined with the loader accepting absolute links found in the raw HTML, the boundary control could be bypassed by any crafted <a href> value.

Attack Vector

Exploitation requires an attacker to control content served at a URL that a victim application crawls. When the victim invokes RecursiveUrlLoader against that URL with prevent_outside=True, the malicious page returns absolute links to attacker-selected hosts, cloud metadata services such as 169.254.169.254, or internal network resources. The loader dereferences those URLs and returns the responses as documents, enabling SSRF and data exfiltration into the LLM context.

python
# Patch excerpt from libs/core/langchain_core/utils/html.py
#     base_url = base_url if base_url is not None else url
+    base_url_to_use = base_url if base_url is not None else url
+    parsed_base_url = urlparse(base_url_to_use)
     all_links = find_all_links(raw_html, pattern=pattern)
     absolute_paths = set()
     for link in all_links:
+        parsed_link = urlparse(link)
         # Some may be absolute links like https://to/path
-        if link.startswith("http"):
-            absolute_paths.add(link)
+        if parsed_link.scheme == "http" or parsed_link.scheme == "https":
+            absolute_path = link
         # Some may have omitted the protocol like //to/path
         elif link.startswith("//"):
-            absolute_paths.add(f"{urlparse(url).scheme}:{link}")
+            absolute_path = f"{urlparse(url).scheme}:{link}"
         else:
-            absolute_paths.add(urljoin(url, link))
+            absolute_path = urljoin(url, parsed_link.path)
+        absolute_paths.add(absolute_path)
# Source: https://github.com/langchain-ai/langchain/commit/bf0b3cc0b5ade1fb95a5b1b6fa260e99064c2e22

Detection Methods for CVE-2024-0243

Indicators of Compromise

  • Outbound HTTP requests from application hosts to unexpected external domains during LangChain crawling jobs.
  • Requests originating from LangChain worker processes to cloud instance-metadata endpoints such as 169.254.169.254, metadata.google.internal, or Azure IMDS.
  • Fetches to internal RFC1918 addresses initiated by processes importing langchain_community.document_loaders.
  • LangChain document caches containing content from hostnames outside the intended seed domain.

Detection Strategies

  • Inventory Python environments for vulnerable langchain and langchain-community versions predating PR #15559.
  • Enable outbound network telemetry from application servers running LangChain and alert on connections that violate an allow-list of expected domains.
  • Instrument the RAG pipeline to log resolved URLs before fetch and compare hostnames against the configured base URL.

Monitoring Recommendations

  • Forward web proxy and egress firewall logs from AI/RAG workloads into a centralized analytics platform for anomaly baselining.
  • Monitor DNS resolutions initiated by LangChain-hosting containers and flag lookups outside the approved corpus domains.
  • Track process-to-network relationships to attribute suspicious egress back to python interpreters running loader code.

How to Mitigate CVE-2024-0243

Immediate Actions Required

  • Upgrade langchain and langchain-community to versions that include the fix from PR #15559.
  • Audit existing RAG corpora for documents pulled from hostnames outside the intended seed domain and purge suspect entries.
  • Restrict egress from LangChain workloads to an allow-list that excludes cloud metadata endpoints and internal management interfaces.

Patch Information

The fix is delivered in the langchain-ai/langchain commit bf0b3cc0. The patch introduces urlparse-based scheme and host checks in libs/core/langchain_core/utils/html.py and further restricts how the recursive URL loader resolves discovered links. Additional context is available in the Huntr bounty listing.

Workarounds

  • Only run RecursiveUrlLoader against trusted, first-party URLs whose content is not attacker-influenced.
  • Wrap loader invocations in an egress proxy that enforces a hostname allow-list independent of application logic.
  • Block access to cloud metadata IPs (169.254.169.254, fd00:ec2::254) at the host or VPC level for RAG workloads.
bash
# Configuration example: pin a patched LangChain release
pip install --upgrade 'langchain>=0.1.0' 'langchain-community>=0.0.9'

# Enforce egress restriction with iptables (Linux example)
iptables -A OUTPUT -d 169.254.169.254 -j REJECT
iptables -A OUTPUT -m owner --uid-owner langchain -d 10.0.0.0/8 -j REJECT

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.