Jun 20, 2026·6 min read·3 visits
High-privileged users can exploit automatic HTTP redirect following in SurrealDB's JWKS fetcher to bypass egress restrictions and perform blind SSRF against internal resources.
A Server-Side Request Forgery (SSRF) vulnerability exists in SurrealDB's Identity & Access Management (IAM) module prior to version 3.1.5. When configuring JSON Web Key Set (JWKS) URLs for token verification, the remote fetcher follows HTTP redirects by default without validating redirect targets against configured network capabilities. This allows high-privileged users to bypass network access limits and perform blind port scanning of internal network resources.
SurrealDB utilizes JSON Web Key Sets (JWKS) to verify signatures on JSON Web Tokens (JWT) used for authentication and authorization. The system administrator defines access methods using the SurrealQL DEFINE ACCESS statement, specifying an external HTTPS URL where the cryptographic keys reside. When a token needs verification, the database server fetches the key set from this remote URL to perform signature validation.
The application contains network egress controls implemented via --allow-net and --deny-net command-line arguments. These arguments restrict the outgoing network paths available to database functions. The JWKS fetcher interacts directly with this network capability system by validating configured URLs before sending requests. However, this implementation was found to be vulnerable to Server-Side Request Forgery (SSRF) due to improper handling of HTTP redirect flows.
The vulnerability is localized within the Identity & Access Management (IAM) module of SurrealDB. Although the initial connection target is evaluated against the configured capabilities, the HTTP client used for the fetch automatically follows 3xx redirection instructions. An attacker controlling an allowed external server can redirect the query to an arbitrary internal IP or loopback interface, bypassing the egress security boundaries.
The vulnerability resides in core/src/iam/jwks.rs where SurrealDB initiates outbound HTTP requests to retrieve JWKS metadata. The application evaluates the configuration parameters through a function named check_capabilities_url to enforce network policies. This function checks the host and port against the allowlists and denylists defined by the database administrator at startup.
If the initial validation succeeds, SurrealDB initiates the fetch using the reqwest HTTP client library in Rust. However, the client is instantiated in its default state without restricting automatic redirection behaviors. By default, reqwest follows HTTP 3xx redirects automatically for up to ten sequential hops without passing the target of each intermediate hop back to the capability verification layer.
Consequently, when an external server responds to the JWKS request with a 302 Found status and a Location header, the HTTP client connects to the new destination. This second-hop request occurs entirely within the internal client loop, completely bypassing check_capabilities_url. This behavior contrasts with the general HttpClient used in other SurrealQL modules, which enforces capability checks on every redirection hop.
The conceptual implementation of the JWKS fetcher before remediation shows that the client lacks custom redirect policies, leading to the blind following of redirect locations.
// Vulnerable Implementation in core/src/iam/jwks.rs
pub async fn fetch_jwks(url: &str) -> Result<Jwks, Error> {
// The check is performed only once on the input string
check_capabilities_url(url)?;
// Default client allows up to 10 redirects automatically
let client = reqwest::Client::new();
let response = client.get(url).send().await?;
// Response is directly parsed as a JWKS JSON document
let jwks = response.json::<Jwks>().await?;
Ok(jwks)
}The patch introduced in version 3.1.5 corrects this vulnerability by constructing a customized redirect policy for the JWKS reqwest client. This policy intercepts every redirection attempt, extracts the target URL, and subjects it to the same check_capabilities_url inspection before proceeding.
// Patched Implementation in core/src/iam/jwks.rs
pub async fn fetch_jwks(url: &str) -> Result<Jwks, Error> {
check_capabilities_url(url)?;
// Build a custom redirect policy to re-validate capabilities
let redirect_policy = reqwest::redirect::Policy::custom(|attempt| {
let target_url = attempt.url().as_str();
// Re-evaluate capability constraints on every hop
if let Err(_) = check_capabilities_url(target_url) {
// Terminate connection if target URL is disallowed
return attempt.stop();
}
// Impose a strict redirect ceiling
if attempt.previous().len() >= MAX_HTTP_REDIRECTS {
return attempt.stop();
}
attempt.follow()
});
// Initialize the client using the hardened policy
let client = reqwest::Client::builder()
.redirect(redirect_policy)
.build()?;
let response = client.get(url).send().await?;
let jwks = response.json::<Jwks>().await?;
Ok(jwks)
}This validation loop ensures that even if an attacker tricks the server into initiating an outbound query, the redirect policy blocks connections to forbidden targets. The validation process remains consistent throughout the entire redirect chain, resolving the security discrepancy.
Exploitation of this vulnerability requires database administrative privileges sufficient to execute DEFINE ACCESS statements. An operator with Owner level access begins by setting up a malicious HTTP redirector on an external, unrestricted IP address. This redirector is configured to return a 302 Found response directing the requester to an internal endpoint, such as the AWS metadata service.
HTTP/1.1 302 Found
Location: http://169.254.169.254/latest/meta-data/
Content-Length: 0Next, the attacker registers a JWT access control mechanism inside SurrealDB that references the malicious redirector URL. Because the initial URL points to a public, external resource, the capabilities check evaluates the domain as authorized and allows the statement to execute without errors.
DEFINE ACCESS target_ssrf ON DATABASE TYPE JWT URL "http://attacker-controlled.com/redirect";Finally, the attacker triggers an authentication request that forces SurrealDB to resolve the JWKS keys. This is accomplished by invoking a SIGNIN query referencing the newly created access method. The server performs the outbound fetch, follows the redirect to the metadata IP, and executes a GET request against the local service.
SIGNIN {
method: "target_ssrf",
token: "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJncm91cHMiOlsiYWRtaW4iXX0.sig"
};Because the response is expected to be a valid JWKS JSON structure, the internal service response fails the parsing stage, yielding an auth failure. Despite this parsing failure, the outbound connection is completed. The attacker can infer the existence of internal services and ports by evaluating the execution timing, as open ports respond immediately while closed or filtered ports hit connection timeouts.
The vulnerability is rated as CVSS 4.1 (Medium Severity) with the vector CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N. The requirement of administrative privileges lowers the threat profile, as only authenticated users with high-level access can define access resources. However, the scope parameter is modified because the vulnerability allows database processes to escape their defined sandboxes and target internal network systems.
The impact is primarily categorized as a blind SSRF. Because the response data must fit a strict JWKS schema, attackers cannot read arbitrary payloads from internal servers. The database will only return a generic authentication error rather than outputting raw HTTP response bodies.
The primary danger is the exposure of internal-only endpoints that do not require additional authentication. For instance, an attacker could trigger administrative actions on unauthenticated internal microservices or retrieve status information via timing-based side channels. The flaw effectively converts the SurrealDB instance into a proxy for internal network reconnaissance.
The definitive remediation for this vulnerability is to upgrade the SurrealDB server instances to version 3.1.5 or newer. This update applies the required custom redirect policies within the IAM JWKS module, neutralizing the redirect bypass vector.
If upgrading is not immediately possible, database administrators should restrict access to administrative roles. Ensuring that only highly trusted personnel have Owner-level database permissions prevents arbitrary JWT definitions.
Furthermore, implementing egress network security controls at the infrastructure level provides robust protection. Setting up firewall rules prevents the SurrealDB process from establishing connections to loopback or RFC 1918 subnets. Additionally, using local, inline cryptographic keys instead of remote JWKS URLs eliminates the need for outbound HTTP requests entirely.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
SurrealDB SurrealDB | < 3.1.5 | 3.1.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS v3.1 Score | 4.1 |
| Exploit Status | none |
| KEV Status | Not Listed |
The web server receives a URL or similar identifier from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
A directory traversal and symlink following vulnerability exists in Pydantic Settings when using the NestedSecretsSettingsSource with nested subdirectory lookups enabled. An attacker capable of writing to the secrets directory can bypass size limitations, read arbitrary host files, or cause a denial-of-service condition via cyclic symlinks.
A local file disclosure vulnerability exists in SurrealDB's full-text search capabilities, allowing authenticated users with database EDITOR or OWNER roles to read arbitrary files from the host system filesystem. This occurs by abusing the mapper() filter inside a DEFINE ANALYZER statement to point to system files.
SurrealDB versions 3.0.0 through 3.1.4 contain an information exposure vulnerability (CWE-203) where the query planner optimizes sorted queries using indexes on fields with field-level SELECT restrictions. Because the query planner performs index-based sorting before enforcing permission-based redaction, unauthorized users can observe the physical order of returned rows to deduce the relative values of protected fields.
A security vulnerability exists in SurrealDB's streaming query planner where streaming graph edge traversals or reverse-reference traversals bypass field-level SELECT permissions. This vulnerability allows an authenticated database user with valid, low-privileged credentials holding table-level SELECT permissions to bypass field-level access controls and read highly confidential or restricted fields.
An authenticated denial-of-service vulnerability in SurrealDB allows remote attackers with query privileges to crash the server process. The issue arises from uncontrolled recursion during the compilation, serialization, or deallocation of exceptionally deep Abstract Syntax Trees (ASTs). While the iterative Pratt parser successfully handles long flat sequences of binary operators without triggering recursion limits, the resulting AST structure causes stack overflow in downstream recursive tree-walking components.
The local media server (mediasrv.py) in Anki up to and including version 25.09.2 fails to validate incoming HTTP requests. The server does not validate the Origin header, enabling cross-origin requests. Additionally, several endpoints suffer from directory traversal vulnerabilities. Combined, these flaws permit an unauthenticated remote attacker to exfiltrate arbitrary files from a local file system when a user visits a malicious website.