Cors Wildcard in Cassandra
How CORS Wildcard Manifests in Cassandra HTTP APIs
Apache Cassandra itself communicates over its native binary protocol, which does not involve HTTP headers and therefore is not subject to Cross‑Origin Resource Sharing (CORS) policies. However, many organizations expose Cassandra data through HTTP‑based interfaces — such as DataStax Astra DB’s REST API, DataStax Enterprise’s HTTP API, or custom microservices built with frameworks like Dropwizard, Spring Boot, or Spark Java. When these services are misconfigured to return the header Access-Control-Allow-Origin: * for every response, a web page loaded from any origin can issue AJAX requests to the Cassandra‑backed endpoint and read the response.
This pattern typically appears in a server‑side filter or interceptor that blindly sets the CORS header without validating the Origin request header. In a Java‑based service using the Servlet API, the problematic code looks like this:
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
// Vulnerable: always allows any origin
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
chain.doFilter(req, res);
}
}
If the service forwards requests to a Cassandra driver (e.g., DataStax Java driver) to execute CQL statements, the attacker can retrieve table data, run administrative commands, or exfiltrate sensitive information simply by embedding a malicious script on a third‑party site. The attack does not require authentication if the HTTP endpoint is unauthenticated, which aligns with middleBrick’s black‑box, unauthenticated scanning model.
Cassandra-Specific Detection with middleBrick
middleBrick’s scanner includes a dedicated CORS check that runs as part of its 12 parallel security tests. When you submit the base URL of a Cassandra‑exposed HTTP API, middleBrick sends a series of OPTIONS and GET requests, inspects the Access-Control-Allow-Origin header, and flags a wildcard (*) as a finding.
Example using the middleBrick CLI:
# Install the CLI (npm)
npm i -g middlebrick
# Scan a Cassandra REST endpoint
middlebrick scan https://cassandra-api.example.com/v1/keyspaces/myks/tables/mytable/rows
The tool returns a JSON report. Below is a trimmed excerpt showing the CORS finding:
{
"scan_id": "a1b2c3d4",
"overall_score": 62,
"grade": "D",
"findings": [
{
"check": "CORS",
"severity": "medium",
"description": "Access-Control-Allow-Origin set to '*' (wildcard) allowing any origin.",
"evidence": {
"header": "Access-Control-Allow-Origin",
"value": "*"
},
"remediation": "Restrict the header to specific trusted origins or implement dynamic origin validation."
}
/* other checks omitted */
]
}
Because middleBrick operates without agents or credentials, the detection works even if the Cassandra HTTP API is behind a load balancer or API gateway, as long as the endpoint is reachable from the public internet.
Cassandra-Specific Remediation: Fixing CORS Wildcard
The fix is to ensure the CORS header reflects only the origins that are legitimately allowed to consume the API. This can be done either at the application level (filter/interceptor) or at the gateway/proxy level. Below are two concrete, Cassandra‑centric examples.
1. Java Servlet Filter with Origin Whitelist
Replace the blanket wildcard with a check against an allowed list (e.g., loaded from an environment variable).
public class SecureCorsFilter implements Filter {
private final Set allowedOrigins;
public SecureCorsFilter() {
String origins = System.getenv("CORS_ALLOWED_ORIGINS");
this.allowedOrigins = (origins == null || origins.isEmpty())
? Collections.emptySet()
: new HashSet<>(Arrays.asList(origins.split(",")));
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String origin = request.getHeader("Origin");
if (origin != null && allowedOrigins.contains(origin)) {
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Credentials", "true");
}
// Optional: handle pre‑flight
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
response.setStatus(HttpServletResponse.SC_OK);
return;
}
chain.doFilter(req, res);
}
}
Deploy this filter in your web.xml or via Spring’s @Bean registration. The environment variable CORS_ALLOWED_ORIGINS should contain a comma‑separated list of trusted origins (e.g., https://app.example.com,https://portal.example.com).
2. DataStax Enterprise HTTP API Configuration
If you are using DataStax Enterprise’s built‑in HTTP API, edit /etc/dse/http.yaml (or the equivalent path in your installation) and replace the wildcard with an explicit list:
cors:
enabled: true
allow_origin: ["https://app.example.com", "https://portal.example.com"]
allow_credentials: true
allow_methods: ["GET", "POST", "OPTIONS"]
allow_headers: ["Content-Type", "Authorization"]
After saving the file, restart the DSE service. The API will now echo back only the originating header when it matches one of the listed values, preventing arbitrary sites from reading Cassandra data via XHR or fetch.
Both approaches preserve the ability for legitimate front‑ends to interact with the Cassandra‑backed service while eliminating the data‑exposure risk introduced by a wildcard CORS policy.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |
Frequently Asked Questions
Does enabling CORS on a Cassandra HTTP API automatically expose my data to the internet?
*) allows any website to retrieve that data. Securing the API (authentication, authorization) and restricting CORS to trusted origins are both required defenses.Can I use middleBrick to verify that my CORS fix works before deploying to production?
Access-Control-Allow-Origin header contains only specific origins (or is absent for same‑origin use), confirming the wildcard has been removed.