Cors Wildcard in Actix with Mutual Tls
Cors Wildcard in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability
A CORS wildcard (Access-Control-Allow-Origin: *) combined with Mutual TLS (mTLS) in Actix can unintentionally broaden the attack surface around authorization and data exposure. In an mTLS setup, the server authenticates the client by verifying a client certificate. Even when mTLS ensures a trusted channel, returning a wildcard Access-Control-Allow-Origin header can weaken the effective boundary between authenticated contexts. If the API also relies on CORS to enforce origin-based access control, the wildcard allows any origin to read responses after a successful mTLS-authenticated request, which can facilitate cross-origin abuse scenarios such as CSRF or unauthorized data leakage in browsers.
Consider an Actix service that uses mTLS for client authentication and also exposes a CORS policy with a wildcard to simplify development. An authenticated client with a valid certificate can make a request from any webpage; the browser will present the certificate and the server will accept it. If the response contains sensitive data and the CORS header permits any origin, a malicious site can embed an image or script that triggers the request and read the response via JavaScript. This does not break mTLS itself, but it undermines the intended scope of access control where origins should be explicitly restricted.
For endpoints that return per-user or per-tenant data, a wildcard origin can enable data exposure across origins when mTLS is used only for transport-level authentication and not for authorizing the origin. This is especially relevant if the API serves both browser clients and non-browser clients; browsers will respect the CORS policy, and a wildcard allows any webpage to initiate authenticated requests, increasing risk of inadvertent data sharing. The combination therefore requires careful alignment between mTLS client identity and explicit origin allowlists rather than relying on a wildcard.
Mutual Tls-Specific Remediation in Actix — concrete code fixes
To remediate CORS issues while preserving mTLS in Actix, explicitly define allowed origins and tie them to the authenticated client identity where feasible. Avoid Access-Control-Allow-Origin: * for endpoints that serve authenticated or sensitive data. Instead, use a dynamic or strict allowlist and, when appropriate, reflect the validated origin only if it is permitted.
Example: mTLS-enabled Actix service with strict CORS
Below is a complete, syntactically correct example that configures mTLS and a restrictive CORS policy in Actix. The server requests and validates client certificates, and CORS is limited to specific origins.
use actix_cors::Cors;
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use std::sync::Arc;
async fn secure_endpoint() -> impl Responder {
HttpResponse::Ok().body("Authenticated and CORS-constrained response")
}
fn cors_policy() -> Cors {
// Explicitly allowlist origins; do not use "*" for authenticated endpoints
let allowed_origin = "https://trusted.example.com";
Cors::default()
.allowed_origin(allowed_origin)
.allowed_methods(vec!["GET".to_string()])
.allowed_headers(vec![actix_web::http::header::AUTHORIZATION, actix_web::http::header::CONTENT_TYPE])
.max_age(3600)
.supports_credentials()
}
fn client_cert_config() -> actix_web::web::Data<Arc<rustls::ServerConfig>> {
// Load server certificate and key
let cert_chain = rustls_pemfile::certs(&mut std::io::BufReader::new(
std::fs::File::open("server-cert.pem").expect("cannot open server cert"),
))
.collect::
Key points in this configuration:
allowed_originis explicitly set to a single trusted origin rather than a wildcard. Adjust this to match your frontend host(s).- Client certificate verification is enforced via
with_client_auth_cert, ensuring only clients with a trusted certificate can establish a TLS session. - CORS headers are applied globally via middleware, ensuring that preflight and actual responses respect the same origin policy.
If you need to support multiple origins, build an allowlist dynamically (e.g., from configuration or a database) and reflect the request origin only when it matches the allowlist. Do not fall back to a wildcard when the origin cannot be validated.
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 |