CVE-2025-28197
Executive Summary
CVE-2025-28197 is a Server-Side Request Forgery (SSRF) vulnerability identified in the Crawl4AI library, specifically within the /crawl4ai/async_dispatcher.py module. This flaw affects versions up to and including 0.4.247. An attacker can exploit this vulnerability to make the server initiate arbitrary HTTP requests to internal or external resources, potentially leading to information disclosure, internal network scanning, or further exploitation of internal services. The vulnerability is classified under MITRE ATT&CK tactic T1190 (Exploit Public-Facing Application) and CWE-918 (Server-Side Request Forgery). No public proof-of-concept (PoC) or exploit code has been released at this time, and no official patch is available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Crawl4AI is a Python package available on PyPI. This vulnerability introduces a significant supply chain risk for any application or service that integrates this library. Organizations using Crawl4AI in their software stack should immediately assess their exposure and consider isolating the affected component until a patch is released. The lack of a patch means that the only current mitigation is to restrict network access from the application or to disable the vulnerable functionality.
CVSS Breakdown & Threat Level
CVSS Score: 0.0 (Uncalculated) CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
Breakdown:
- Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low (L) - No special conditions are required for exploitation.
- Privileges Required (PR): None (N) - No authentication is needed.
- User Interaction (UI): None (N) - The victim does not need to perform any action.
- Scope (S): Changed (C) - The vulnerable component impacts resources beyond its security scope.
- Confidentiality (C): High (H) - Successful exploitation can lead to disclosure of sensitive internal data.
- Integrity (I): None (N) - The vulnerability does not allow modification of data.
- Availability (A): None (N) - The vulnerability does not affect system availability.
Threat Level: High. The combination of network exploitability, low complexity, and potential for significant information disclosure makes this a critical risk for affected deployments.
Deep Dive & Mechanics
The vulnerability resides in the async_dispatcher.py module of Crawl4AI. The AsyncDispatcher class is responsible for managing asynchronous crawling tasks. The flaw occurs when the dispatcher processes user-supplied URLs or redirects without proper validation. Specifically, the code does not sanitize or restrict the target URLs that the crawler can access.
Mechanism:
- An attacker sends a crafted request to the Crawl4AI service, providing a malicious URL (e.g.,
http://169.254.169.254/latest/meta-data/for AWS metadata). - The
AsyncDispatcherreceives this URL and passes it to the underlying HTTP client (likelyaiohttpor similar). - The HTTP client makes a request to the attacker-specified URL, which could be an internal IP address, a cloud metadata endpoint, or a service on the local network.
- The response from the internal resource is then returned to the attacker, leaking sensitive information.
The core issue is the lack of a URL allowlist or blocklist, and the absence of validation to prevent requests to private IP ranges (e.g., 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and 169.254.0.0/16).
Vulnerable vs. Patched Code
Vulnerable Code (Crawl4AI <= 0.4.247):
The vulnerable code in async_dispatcher.py likely resembles the following pattern, where user input is directly used to create a request without validation.
# Vulnerable async_dispatcher.py (simplified)
async def crawl_url(self, url: str):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
Patched Code (Hypothetical): A patched version would include validation to ensure the URL does not point to private or reserved IP ranges.
# Patched async_dispatcher.py (hypothetical)
import ipaddress
from urllib.parse import urlparse
async def crawl_url(self, url: str):
parsed = urlparse(url)
host = parsed.hostname
try:
ip = ipaddress.ip_address(host)
if ip.is_private or ip.is_loopback or ip.is_link_local:
raise ValueError("URL points to a private or reserved IP address")
except ValueError:
raise
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
Exploitation & Lab Setup
Red Team
Objective: Exploit the SSRF vulnerability to access internal resources.
Lab Setup:
- Target: A server running Crawl4AI version 0.4.247 with the vulnerable
async_dispatcher.py. - Attacker Machine: Kali Linux or any system with
curlorpython3. - Internal Resource: A simulated internal service (e.g., a web server on 127.0.0.1:8080 or a cloud metadata endpoint).
Exploitation Steps:
- Identify the Crawl4AI endpoint that accepts URLs. This is typically a REST API endpoint like
/crawlor/fetch. - Send a POST request with a malicious URL pointing to an internal resource.
curl -X POST http://target:5000/crawl \
-H "Content-Type: application/json" \
-d '{"url": "http://127.0.0.1:8080/admin"}'
- If the internal service returns data, the response will be reflected back to the attacker.
Advanced Exploitation:
- Use DNS rebinding to bypass simple hostname checks.
- Exploit cloud metadata endpoints (e.g.,
http://169.254.169.254/latest/meta-data/for AWS). - Scan internal network ranges to discover services.
Blue Team
Objective: Detect and block SSRF attempts.
Detection Steps:
- Monitor outbound HTTP requests from the Crawl4AI server to private IP ranges.
- Implement network segmentation to restrict the Crawl4AI server's outbound access.
- Use a Web Application Firewall (WAF) to block requests containing private IP addresses in the URL.
Mitigation in Code:
- Apply input validation to reject URLs pointing to private IPs.
- Use a URL allowlist to restrict crawling to trusted domains only.
Indicators of Compromise (IOCs)
Network IOCs:
- Outbound HTTP requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16).
- Requests to cloud metadata endpoints (e.g.,
169.254.169.254). - Unusual DNS queries for internal hostnames.
File IOCs:
- Log entries in Crawl4AI logs showing requests to internal IPs.
- Modified configuration files that disable security checks.
Behavioral IOCs:
- Unexpected increase in outbound traffic from the Crawl4AI server.
- Access to internal services that are not normally accessed by the application.
Detection Engineering
YARA Rule
rule CVE_2025_28197_SSRF_Crawl4AI {
meta:
description = "Detects SSRF exploitation attempts against Crawl4AI"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-28197"
strings:
$url_pattern = /(http|https):\/\/(127\.0\.0\.1|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3})/
$crawl4ai_ref = "async_dispatcher.py"
condition:
$url_pattern and $crawl4ai_ref
}
Sigma Rule
title: SSRF Attempt Against Crawl4AI
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP requests from Crawl4AI to private IP addresses
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-uri-query|contains:
- '127.0.0.1'
- '10.'
- '172.16.'
- '172.17.'
- '172.18.'
- '172.19.'
- '172.20.'
- '172.21.'
- '172.22.'
- '172.23.'
- '172.24.'
- '172.25.'
- '172.26.'
- '172.27.'
- '172.28.'
- '172.29.'
- '172.30.'
- '172.31.'
- '192.168.'
- '169.254.'
condition: selection
falsepositives:
- Legitimate internal crawling if allowed
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-28197 SSRF Attempt Against Crawl4AI"; flow:to_server; content:"GET"; http_method; content:"/crawl"; http_uri; pcre:"/(127\.0\.0\.1|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3})/Ri"; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Isolate the Service: Place the Crawl4AI service in a segmented network with strict egress filtering to prevent access to internal resources.
- Disable Vulnerable Functionality: If possible, disable the URL crawling feature until a patch is available.
- Apply Input Validation: Implement a reverse proxy or WAF to block requests containing private IP addresses.
Long-Term Fix:
- Monitor the Crawl4AI repository for an official patch. Once released, update to the patched version immediately.
- Conduct a code review to ensure all user-supplied URLs are validated against an allowlist.
Workaround:
- Modify the
async_dispatcher.pyfile to include IP validation as shown in the patched code example above.
Valters IT