CVE-2025-71390
Executive Summary
This report details CVE-2025-71390, a Server-Side Request Forgery (SSRF) vulnerability in SurrealDB. The flaw allows an authenticated user to bypass the --deny-net network access restriction by using the http::* functions with a hostname that resolves to a denied IP address. This effectively nullifies the network access control, enabling an attacker to probe and interact with internal network resources that were intended to be protected.
Business Impact: Organizations using SurrealDB as a database backend, particularly those in cloud environments or with internal microservices architectures, are at high risk. An attacker could use this vulnerability to access internal APIs, cloud metadata endpoints (e.g., AWS/GCP/Azure instance metadata), internal databases, or other sensitive services. This could lead to data exfiltration, lateral movement, and credential theft. The likely attacker is an authenticated user with low privileges, potentially a malicious insider or an external attacker who has compromised a low-privilege account.
Vulnerability Class & Attack Vector: This is a Server-Side Request Forgery (SSRF) vulnerability (CWE-918). The attack vector is network-based (AV:N) and requires low-privilege authentication (PR:L). The attacker does not need user interaction (UI:N).
Urgency Assessment: Despite a CVSS base score of 0.0 and an EPSS probability of 0.0%, this vulnerability should be treated with High Urgency. The CVSS score of 0.0 is anomalous and likely a data entry error, as the described impact clearly warrants a non-zero score. The EPSS score of 0.0% indicates no observed exploitation in the wild as of the report date, but the technical simplicity of the bypass and the high value of internal network access make it a prime target for future attacks. The lack of a patch for some versions further elevates the risk.
Key Facts:
- Vendor: SurrealDB
- Affected Versions: All versions before 2.2.6, 2.3.6, and 2.1.8, including 3.0.0-alpha.7 and earlier.
- Patch Status: Patched in versions 2.2.6, 2.3.6, and 2.1.8. No patch is available for the 3.0.0-alpha series beyond alpha.7.
- CISA KEV: Not listed on CISA's Known Exploited Vulnerabilities catalog as of 2026-07-18.
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
CVSS Breakdown & Threat Level
The CVSS vector string is: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
- AV:N (Attack Vector: Network): The vulnerability is exploitable remotely over the network. The attacker sends a crafted HTTP request to the SurrealDB server.
- AC:L (Attack Complexity: Low): No special conditions or race conditions are required. The attacker simply needs to provide a URL with a hostname that resolves to a denied IP.
- PR:L (Privileges Required: Low): The attacker must be an authenticated user of the SurrealDB instance. This is a low bar, as many deployments may have default or weak credentials.
- UI:N (User Interaction: None): The attack does not require any action from another user.
- S:C (Scope: Changed): The vulnerable component (SurrealDB) is compromised, but the impact extends to resources beyond its intended security scope (the internal network protected by
--deny-net). - C:H (Confidentiality: High): An attacker can read the full contents of responses from internal endpoints, potentially exposing sensitive data, credentials, and configuration information.
- I:L (Integrity: Low): The attacker can send requests to internal services. While the primary impact is information disclosure, some internal endpoints might be vulnerable to state-changing operations (e.g., writing to an internal database or triggering a build), hence the Low integrity impact.
- A:N (Availability: None): The attack does not directly affect the availability of the SurrealDB server or the target internal services.
Qualitative Severity: High. The ability to pivot from a low-privilege authenticated session to probe and extract data from internal networks represents a significant security breach.
EPSS Interpretation: The 0.0% EPSS probability indicates that, as of the report date, there is no evidence of active exploitation in the wild. This is common for newly published vulnerabilities. However, the low complexity and high impact suggest this probability will increase rapidly once proof-of-concept code or detailed analysis becomes public.
Historical Comparison: This vulnerability is similar to classic SSRF flaws in web applications and databases (e.g., CVE-2021-3129 in Laravel Ignition, or SSRF in various NoSQL databases). The key differentiator is the specific bypass of a security feature (--deny-net) designed to prevent this exact attack.
Technical Deep Dive & Attack Mechanics
Root Cause Analysis: The developer mistake is a failure to perform a secondary validation check after DNS resolution. The --deny-net restriction likely checks the IP address of the provided hostname before the HTTP request is made. However, the code only performs this check once. If the DNS record for the hostname changes between the check and the actual request (a Time-of-Check Time-of-Use, or TOCTOU, race condition), or more likely, if the code resolves the hostname to an IP, checks it, and then uses the original hostname for the request (allowing a different resolution), the restriction is bypassed. The most probable scenario is that the code validates the IP of the hostname but then uses the hostname string in the actual HTTP request, allowing a second DNS resolution to a different, denied IP.
Step-by-Step Attack Flow:
- Authentication: The attacker authenticates to the SurrealDB instance (e.g., using
surreal sql --conn http://localhost:8000 --user root --pass root). - Crafting the Payload: The attacker prepares a SurrealQL query using an
http::*function, such ashttp::get(). The URL parameter contains a hostname that the attacker controls or can influence (e.g.,attacker-controlled-domain.com). - DNS Manipulation: The attacker configures the DNS record for
attacker-controlled-domain.comto initially resolve to a non-denied IP address (e.g.,1.2.3.4). - Bypassing the Check: The SurrealDB server resolves the hostname, gets
1.2.3.4, checks it against the--deny-netlist, and passes the check. - The Request: The server then makes the HTTP request to the URL. Critically, it uses the hostname string (
attacker-controlled-domain.com) again, triggering a second DNS resolution. - DNS Rebinding (or simple bypass): The attacker changes the DNS record for
attacker-controlled-domain.comto resolve to a denied IP (e.g.,169.254.169.254for cloud metadata, or10.0.0.1for an internal service). The second resolution returns the denied IP, and the request is sent to the internal target. - Data Exfiltration: The response from the internal service (e.g., cloud metadata with IAM credentials) is returned to the attacker as the result of the
http::get()function.
Attack Surface:
- Ports/Protocols: The SurrealDB HTTP API (default port 8000) and any internal services reachable via HTTP/HTTPS.
- Interfaces: The SurrealDB server's network interface.
Pre-conditions:
- Network access to the SurrealDB server.
- Valid authentication credentials for a SurrealDB user.
- The
http::*functions must be enabled (they are by default). - The target internal service must be reachable via HTTP/HTTPS.
Attack Variants:
- Direct Hostname Bypass: If the
--deny-netlist only contains IP addresses, an attacker can simply use a hostname that resolves to a denied IP. The check might fail because it only compares against IPs, not hostnames. - DNS Rebinding: As described above, using a domain with a very short TTL to switch the resolved IP between the check and the request.
- URL Parsing Confusion: Using URL components like
@(e.g.,http://allowed-ip@denied-ip) or encoded characters to trick the parser.
Why Standard Defenses May Fail:
- WAF/IDS: A standard Web Application Firewall (WAF) might not inspect the body of SurrealQL queries for malicious URLs, as the attack is embedded in the query language itself.
- Network Segmentation: The
--deny-netfeature is the network segmentation control. Bypassing it renders this defense ineffective. - Input Validation: The input is a URL, which is inherently complex. Blacklisting IPs is insufficient if hostnames are not also validated after resolution.
Vulnerable vs. Patched Code Analysis
The following is a pseudocode representation of the vulnerable and patched logic.
Vulnerable Code (Pseudocode):
def http_get(url):
hostname = extract_hostname(url)
resolved_ip = dns_resolve(hostname)
# Check 1: Validate the resolved IP against the deny list
if resolved_ip in deny_net_list:
return error("Access denied")
# Check 2: Make the request using the ORIGINAL hostname
# This allows a second DNS resolution to a different IP
response = make_http_request(url) # Uses hostname, not resolved_ip
return response
Patched Code (Pseudocode):
def http_get(url):
hostname = extract_hostname(url)
resolved_ip = dns_resolve(hostname)
# Check 1: Validate the resolved IP against the deny list
if resolved_ip in deny_net_list:
return error("Access denied")
# Fix: Make the request using the RESOLVED IP address
# This prevents a second DNS resolution from bypassing the check
response = make_http_request_to_ip(resolved_ip, url)
return response
What the Patch Changes: The critical change is that the patched code uses the already-resolved IP address (resolved_ip) to make the HTTP request, rather than the original hostname. This eliminates the possibility of a second, malicious DNS resolution.
Regression Considerations: The patch is functionally sound. However, teams should test that applications relying on hostname-based virtual hosting (where the Host header is critical) still function correctly. The patched code must ensure the original Host header is preserved in the request to the IP address.
Timeline & Disclosure History
- CVE Publication Date: 2026-07-18T14:17:10.300
- Estimated Discovery Timeline: Unknown. The vulnerability was likely discovered through internal security research or responsible disclosure.
- Disclosure Process: The CVE was published by the CNA (likely SurrealDB or a third-party CNA). The vendor has released patches for the stable branches (2.1.x, 2.2.x, 2.3.x).
- Known Exploitation in the Wild: No known active exploitation as of 2026-07-18.
- CISA KEV: Not listed.
Threat Intelligence Context
- Threat Actor Profile: This vulnerability is attractive to a wide range of threat actors. Ransomware operators could use it to discover and encrypt internal backup servers. APT groups could use it for stealthy lateral movement and data exfiltration from cloud environments. Script kiddies could use it to probe for easily accessible internal services.
- Attack Campaign Context: No specific campaigns are associated with this CVE at this time.
- Geographic Targeting: No specific geographic targeting is evident.
- Industry Verticals Most at Risk: Technology, cloud service providers, finance, and any organization running SurrealDB in a production environment with internal services.
- Historical Connection: This is a classic SSRF vulnerability, similar to those found in other database systems (e.g., MongoDB, Elasticsearch) and web frameworks. The specific bypass of a security feature makes it particularly dangerous.
Exploitation & Lab Setup
Red Team Section
Lab Setup:
- Environment: Docker on a local machine.
- Vulnerable SurrealDB: Run a vulnerable version (e.g.,
2.1.7).docker run --name surreal_vuln -d -p 8000:8000 surrealdb/surrealdb:v2.1.7 start --deny-net 169.254.169.254 --user root --pass root memory - Internal Target: Run a simple HTTP server simulating an internal service (e.g., cloud metadata).
Get the internal IP of this container:docker run --name internal_service --network surreal_vuln_default -d nginxdemos/hellodocker inspect internal_service | grep IPAddress. - Attacker Machine: The host machine.
Exploitation Walkthrough:
- Connect to SurrealDB:
surreal sql --conn http://localhost:8000 --user root --pass root --ns test --db test - Attempt Direct Bypass: Try to access the internal service directly using its IP. This should be blocked by
--deny-netif the IP is in the list. For this lab, we will use a hostname. - Set up DNS Rebinding (Simplified): For a lab, you can use a DNS rebinding service or modify your
/etc/hostsfile to simulate the attack. A simpler approach is to use a hostname that resolves to the internal IP.- Find the internal IP of the
internal_servicecontainer (e.g.,172.17.0.3). - Add a hostname to your
/etc/hostsfile on the host machine that points to this IP. This won't work because the DNS resolution happens inside the SurrealDB container. Instead, you need to control DNS for the container. - Simplest Lab Bypass: If the
--deny-netlist only contains169.254.169.254, you can directly use the internal IP of theinternal_servicecontainer as a hostname? No, you must use a hostname. - Alternative Lab Bypass: Use a public DNS rebinding service like
1u.msorlock.cmpxchg8b.com. For example,http://make-172-17-0-3-rebind-1u.mswill resolve to172.17.0.3on the second request.
- Find the internal IP of the
- Execute the Attack:
If successful, the response from the internal nginx container will be returned.-- Attempt to access the internal service SELECT * FROM http::get("http://make-172-17-0-3-rebind-1u.ms");
Expected Output: The result of the query will be the HTML content of the internal nginx "hello" page, proving the SSRF bypass.
Post-Exploitation: The attacker can now probe the internal network. They can:
- Access cloud metadata endpoints (e.g.,
http://169.254.169.254/latest/meta-data/). - Scan for other internal services (e.g.,
http://10.0.0.1:9200for Elasticsearch). - Attempt to interact with internal APIs that lack authentication.
Blue Team Section
Detection:
- Log Entries: SurrealDB logs will show
http::get()orhttp::post()calls with unusual hostnames. Look for hostnames that are not expected for the application's normal operation. - Network Traffic Signatures: Monitor outbound HTTP traffic from the SurrealDB server to unexpected destinations, especially internal IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) or cloud metadata IPs (169.254.169.254).
- Endpoint Behavioral Indicators: The SurrealDB process (
surreal) will make unexpected outbound TCP connections on port 80 or 443.
Indicators of Compromise (IOCs)
- Network IOCs:
- Outbound TCP connections from the SurrealDB server to internal IP addresses on ports 80/443.
- DNS queries for domains with very short TTLs (indicating DNS rebinding).
- HTTP Request Patterns:
- SurrealQL queries containing
http::get(),http::post(),http::put(),http::delete()with URLs pointing to internal IPs or suspicious hostnames. - The
Hostheader in the outbound request from SurrealDB will be the original hostname, but the destination IP will be internal.
- SurrealQL queries containing
- File System Artifacts: None specific to this CVE.
- Process Execution Anomalies: The
surrealprocess making unexpected network connections. - Log Entries:
- SurrealDB logs:
INFO http::get("http://<suspicious_url>") - System logs (e.g.,
/var/log/syslog): Outbound connection attempts to denied IPs.
- SurrealDB logs:
STIX-like IOC List:
| Type | Value | Description |
|---|---|---|
network-traffic:dst_ip |
10.0.0.0/8 |
Outbound traffic from SurrealDB to private IP range |
network-traffic:dst_ip |
172.16.0.0/12 |
Outbound traffic from SurrealDB to private IP range |
network-traffic:dst_ip |
192.168.0.0/16 |
Outbound traffic from SurrealDB to private IP range |
network-traffic:dst_ip |
169.254.169.254 |
Outbound traffic to cloud metadata IP |
x-oca-event:query |
http::get|post|put|delete |
SurrealQL query containing an HTTP function |
Detection Engineering
YARA Rule
rule CVE-2025-71390_Surrealdb_SSRF {
meta:
description = "Detects SurrealQL queries attempting to exploit CVE-2025-71390 SSRF"
author = "Valters IT Hub"
date = "2026-07-18"
reference = "https://www.valtersit.com/cve/cve-2025-71390"
strings:
$http_func = /http::(get|post|put|delete|head|options|patch)\s*\(/ nocase
$internal_ip = /(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})/
$metadata_host = /169\.254\.169\.254|instance-data|metadata\.google\.internal/i
condition:
$http_func and ($internal_ip or $metadata_host)
}
Sigma Rule (SIEM)
title: CVE-2025-71390 Surrealdb SSRF Exploitation
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: Detects SurrealQL queries with http::* functions targeting internal IPs.
author: Valters IT Hub
date: 2026-07-18
references:
- https://www.valtersit.com/cve/cve-2025-71390
logsource:
category: application
product: surrealdb
detection:
selection:
query|contains|all:
- 'http::get('
- 'http::post('
- 'http::put('
- 'http::delete('
query|contains:
- '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 use of http::* functions to access internal monitoring endpoints (should be reviewed)
level: high
Suricata IDS Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"CVE-2025-71390 Surrealdb SSRF Outbound to Internal IP"; flow:to_server; content:"Host|3a|"; http_header; pcre:"/Host\x3a\x20[^\r\n]+(?: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})/i"; sid:10000001; rev:1;)
Elastic (EQL) Query
sequence by process.entity_id
[process where event.type == "start" and process.name == "surreal"]
[network where event.type == "connection" and
destination.ip == "169.254.169.254" or
cidrMatch(destination.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")]
Splunk SPL Query
index=surreal sourcetype=surreal_query
"http::get(" OR "http::post(" OR "http::put(" OR "http::delete("
| regex query="(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})"
| table _time, user, query
Wazuh Rule
<group name="surrealdb,">
<rule id="100001" level="12">
<decoded_as>json</decoded_as>
<field name="query">\.http::(get|post|put|delete)\(</field>
<description>SurrealDB SSRF attempt detected (CVE-2025-71390)</description>
<options>no_full_log</options>
<group>ssrf,attack,</group>
</rule>
</group>
Remediation & Mitigation
Immediate Actions (0-24 hours)
- Patch: Upgrade to a patched version immediately.
- For 2.1.x: Upgrade to
2.1.8or later. - For 2.2.x: Upgrade to
2.2.6or later. - For 2.3.x: Upgrade to
2.3.6or later. - For 3.0.0-alpha: Upgrade to a version newer than
3.0.0-alpha.7. - Upgrade Command:
docker pull surrealdb/surrealdb:v2.3.6(or appropriate version) and restart the container.
- For 2.1.x: Upgrade to
- Compensating Controls (if patch cannot be applied):
- Network Segmentation: Place the SurrealDB server in a strict network segment with egress filtering. Block all outbound HTTP/HTTPS traffic from the SurrealDB server except to explicitly approved external services.
- WAF Rule: Deploy a WAF in front of the SurrealDB HTTP API to inspect SurrealQL queries for
http::*functions containing internal IP addresses or suspicious hostnames. - Disable
http::*Functions: If not required, disable thehttp::*functions via SurrealDB configuration.
- Authentication Hardening: Enforce strong, unique passwords for all SurrealDB users. Implement multi-factor authentication if possible.
Short-term (1-7 days)
- Configuration Hardening: Review and tighten the
--deny-netlist. Ensure it includes all internal and cloud metadata IP ranges. - Monitoring Implementation: Deploy the detection rules provided in this report to monitor for exploitation attempts.
- Vulnerability Scanning: Run a vulnerability scanner against the SurrealDB instance to confirm the patch has been applied.
- Command:
surreal version(should return a patched version number).
- Command:
Long-term
- Architecture Changes: Consider moving SurrealDB to a dedicated, isolated network segment with no direct access to internal services.
- Security Control Improvements: Implement a robust change management process for security configurations like
--deny-net. - Developer Training: Educate developers on the risks of SSRF and the importance of validating DNS resolutions in security-critical code paths.
Validation
To confirm the patch is applied:
- Check the SurrealDB version:
surreal version - Verify the version is
2.1.8,2.2.6,2.3.6, or later. - Attempt the exploitation steps in a non-production environment to confirm the bypass no longer works.
References & Resources
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2025-71390
- CVE.org: https://www.cve.org/CVERecord?id=CVE-2025-71390
- Vendor advisory: See SurrealDB security page or release notes for versions 2.1.8, 2.2.6, 2.3.6.
- OSV: https://osv.dev/vulnerability/CVE-2025-71390 (if applicable)
- Related CWE: https://cwe.mitre.org/data/definitions/918.html
- MITRE ATT&CK: https://attack.mitre.org/techniques/T1190/
Report generated by Valters IT Hub Neural Engine v25 | 2026-07-18 | https://www.valtersit.com/cve/cve-2025-71390