Cors Wildcard with Mutual Tls
How CORS Wildcard Manifests in Mutual TLS
CORS wildcard configurations in Mutual TLS environments create a unique attack surface that combines the flexibility of certificate-based authentication with the risks of overly permissive cross-origin policies. When Mutual TLS is deployed, servers typically validate client certificates to establish identity before processing any request. However, if the same server implements a wildcard CORS policy like Access-Control-Allow-Origin: *, it creates a scenario where any client with a valid certificate can access resources from any origin.
The most common manifestation occurs in enterprise API gateways that use Mutual TLS for internal service authentication but expose administrative endpoints to browser-based management consoles. Consider a scenario where an internal API at api.internal.company.com requires client certificates for authentication. If this API also includes a wildcard CORS header, any authenticated client can make cross-origin requests from external domains, effectively bypassing the network segmentation that Mutual TLS was designed to enforce.
Attackers exploit this by obtaining a valid client certificate through various means—compromised developer machines, insider threats, or certificate theft from CI/CD pipelines. Once they have a certificate, they can use it to authenticate with the Mutual TLS endpoint and then leverage the wildcard CORS policy to make requests from malicious origins. This is particularly dangerous for APIs that expose sensitive administrative functions or data export capabilities.
A specific attack pattern involves using the wildcard CORS policy to exfiltrate data through browser-based tools. An attacker with a stolen certificate can host a malicious website that makes authenticated requests to the target API and then exfiltrates the response data back to their controlled domain. The Mutual TLS authentication succeeds because the certificate is valid, and the wildcard CORS policy allows the cross-origin response to be read by the malicious JavaScript.
Another manifestation occurs in development environments where Mutual TLS is used for service-to-service communication, but development tools like Swagger UI or API documentation portals are exposed with wildcard CORS. Developers often test APIs from their browsers using these tools, and if the underlying services have wildcard CORS policies, any authenticated request from these tools can be made from arbitrary origins.
The combination of Mutual TLS and wildcard CORS is particularly insidious because it creates a false sense of security. Organizations believe that since Mutual TLS requires certificate authentication, they don't need to worry about cross-origin requests. However, the wildcard CORS policy completely undermines this security model by allowing any authenticated client to make requests from any origin.
Mutual TLS-Specific Detection
Detecting CORS wildcard issues in Mutual TLS environments requires a specialized approach that combines certificate validation with CORS policy analysis. Traditional CORS scanners that don't account for Mutual TLS will miss these vulnerabilities because they can't authenticate with the server using client certificates.
The detection process starts with establishing a Mutual TLS connection using a test certificate. This certificate should be valid for testing purposes but not have production privileges. Once connected, the scanner sends preflight OPTIONS requests with various Origin headers to identify wildcard CORS policies. A server that responds with Access-Control-Allow-Origin: * or echoes back arbitrary Origin headers is vulnerable.
middleBrick's approach to detecting this specific issue involves several steps. First, it establishes a Mutual TLS connection using its built-in certificate store. Then it performs a series of cross-origin requests from different domains, including known malicious patterns like data: URIs and javascript: URIs. If the server responds with CORS headers that allow these origins, it indicates a wildcard or overly permissive policy.
The scanner also checks for CORS misconfigurations specific to Mutual TLS environments. For example, some APIs implement certificate-based authentication but also maintain session cookies for browser-based access. If these APIs have wildcard CORS policies, an attacker could potentially bypass certificate authentication by using a session cookie obtained through other means.
middleBrick's LLM/AI security features also detect when wildcard CORS policies are combined with AI/ML endpoints that use Mutual TLS. These endpoints might expose system prompts or model parameters that could be extracted through cross-origin requests if the CORS policy is too permissive.
Another detection technique involves analyzing the API's OpenAPI specification if available. The scanner looks for endpoints that are documented as requiring Mutual TLS authentication but also have CORS headers defined in the spec. This helps identify APIs where the developers may have overlooked the CORS implications of their Mutual TLS deployment.
The detection process also includes checking for CORS preflight caching issues. Some Mutual TLS APIs cache CORS preflight responses, which can lead to situations where a temporary wildcard policy becomes persistent. The scanner tests this by making repeated preflight requests and observing whether the CORS headers change over time.
middleBrick's continuous monitoring feature is particularly valuable for detecting changes in CORS policies over time. Organizations can set up monitoring to alert them if a previously secure CORS policy suddenly becomes wildcard, which might indicate a configuration drift or a security incident.
Mutual TLS-Specific Remediation
Remediating CORS wildcard issues in Mutual TLS environments requires a careful balance between maintaining the security benefits of certificate-based authentication while properly restricting cross-origin access. The primary remediation is to replace wildcard CORS policies with specific, origin-based policies that only allow trusted domains.
For Node.js applications using Express with Mutual TLS middleware, the remediation involves configuring CORS with an explicit origin list:
const express = require('express');
const cors = require('cors');
const https = require('https');
const fs = require('fs');
const app = express();
// Mutual TLS configuration
const httpsOptions = {
cert: fs.readFileSync('/path/to/server-cert.pem'),
key: fs.readFileSync('/path/to/server-key.pem'),
ca: [fs.readFileSync('/path/to/ca-cert.pem')],
requestCert: true,
rejectUnauthorized: true
};
// Whitelist of allowed origins
const allowedOrigins = [
'https://admin.company.com',
'https://dashboard.company.com',
'https://api.company.com'
];
// Configure CORS with origin validation
app.use(cors({
origin: function(origin, callback) {
if (!origin) return callback(null, true); // Allow requests without origin
if (allowedOrigins.indexOf(origin) !== -1) {
return callback(null, true);
}
return callback(new Error('Not allowed by CORS'));
},
credentials: true
}));
// API endpoints
app.get('/api/data', (req, res) => {
// Mutual TLS already validated by HTTPS layer
res.json({ message: 'Secure data' });
});
// Start server
https.createServer(httpsOptions, app).listen(3000, () => {
console.log('Mutual TLS server with CORS restrictions running on port 3000');
});
For Python applications using Flask with Mutual TLS, the remediation involves similar principles:
from flask import Flask, jsonify
from flask_cors import CORS
import ssl
app = Flask(__name__)
# Allowed origins for CORS
allowed_origins = [
"https://admin.company.com",
"https://dashboard.company.com",
"https://api.company.com"
]
# Configure CORS
cors = CORS(app, resources={
r"/api/*": {"origins": allowed_origins}
})
# Mutual TLS context
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile='/path/to/server-cert.pem',
keyfile='/path/to/server-key.pem')
context.load_verify_locations(cafile='/path/to/ca-cert.pem')
context.verify_mode = ssl.CERT_REQUIRED
@app.route('/api/data')
def get_data():
return jsonify(message="Secure data")
if __name__ == '__main__':
app.run(ssl_context=context, port=3000)
For Java applications using Spring Boot with Mutual TLS, the remediation involves configuring both the CORS filter and the SSL context:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
@Configuration
public class SecurityConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// Allow only specific origins
config.setAllowedOrigins(List.of(
"https://admin.company.com",
"https://dashboard.company.com",
"https://api.company.com"
));
config.setAllowedMethods(List.of(
"GET", "POST", "PUT", "DELETE", "OPTIONS"
));
config.setAllowedHeaders(List.of(
"Content-Type", "Authorization", "X-Requested-With"
));
config.setAllowCredentials(true);
source.registerCorsConfiguration("/api/**", config);
return new CorsFilter(source);
}
@Bean
public SSLContext sslContext() throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("/path/to/keystore.p12"), "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
}
}
For NGINX reverse proxy configurations that handle Mutual TLS termination, the remediation involves configuring both SSL and CORS headers:
server {
listen 443 ssl http2;
server_name api.company.com;
# Mutual TLS configuration
ssl_certificate /path/to/server-cert.pem;
ssl_certificate_key /path/to/server-key.pem;
ssl_client_certificate /path/to/ca-cert.pem;
ssl_verify_client on;
# CORS configuration with specific origins
location /api/ {
if ($http_origin ~* ^(https://admin\.company\.com|https://dashboard\.company\.com)$) {
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
}
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Content-Type' 'text/plain; charset=utf-8' always;
add_header 'Content-Length' '0' always;
return 204;
}
# Proxy to backend
proxy_pass http://backend-service:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The key principle across all these remediations is to maintain the security benefits of Mutual TLS authentication while properly restricting cross-origin access. This means never using wildcard CORS policies (*) and instead explicitly listing only the trusted origins that need access to the API.
Organizations should also implement monitoring to detect if CORS policies are changed to wildcard configurations. This can be done through configuration management tools that alert on changes to CORS settings, or through continuous security scanning with tools like middleBrick that can detect these issues automatically.
For APIs that need to be accessible from multiple internal domains but not external ones, consider implementing a more sophisticated origin validation that checks against a whitelist of internal domains. This can be combined with additional security headers like Content-Security-Policy to further restrict how the API responses can be used.
Finally, document the CORS policies as part of your API security documentation. This helps developers understand the security model and ensures that any future changes to the API's CORS configuration are made with full awareness of the security implications.
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
How does Mutual TLS authentication interact with CORS policies in practice?
Can middleBrick detect CORS wildcard issues in Mutual TLS environments?
Access-Control-Allow-Origin: * responses, origin echoing, and other permissive CORS configurations. middleBrick's 12 security checks include specific tests for CORS misconfigurations, and its continuous monitoring feature can alert you if CORS policies change over time. The tool provides detailed findings with severity levels and remediation guidance, helping you understand exactly where your Mutual TLS APIs have overly permissive CORS policies that could be exploited.