Cors Wildcard in Actix
How Cors Wildcard Manifests in Actix
CORS wildcard misconfigurations in Actix applications create a specific attack vector that allows any origin to access your API resources. This vulnerability occurs when developers use overly permissive CORS settings, particularly the wildcard (*) origin, without understanding the security implications.
In Actix, the most common manifestation appears when developers use the cors::Cors middleware with default or wildcard settings. Consider this vulnerable Actix code:
use actix_web::{web, App, HttpServer, HttpResponse};
use actix_cors::Cors;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(
Cors::permissive() // 🚨 VULNERABLE: Allows all origins
)
.service(web::resource("/api").route(web::get().to(|| HttpResponse::Ok())))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
The Cors::permissive() method enables all CORS headers with wildcard origins, allowing any website to make cross-origin requests to your Actix API. This becomes particularly dangerous when combined with authentication cookies or when the API exposes sensitive data.
Another common pattern in Actix applications:
App::new()
.wrap(
Cors::default()
.allowed_origin("*") // 🚨 VULNERABLE: Wildcard origin
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
.allowed_headers(vec!["Content-Type", "Authorization"])
)
This configuration allows any origin to send requests with any of the specified methods and headers. Attackers can host malicious websites that make authenticated requests to your API on behalf of logged-in users, exploiting the browser's same-origin policy bypass.
The vulnerability becomes more severe when Actix applications handle authentication. Consider this pattern:
App::new()
.wrap(
Cors::default()
.allowed_origin("*")
.supports_credentials() // 🚨 DANGEROUS COMBINATION
.allowed_methods(vec!["GET", "POST"])
)
.service(web::resource("/user/profile").route(web::get().to(get_profile)))
When supports_credentials(true) is combined with a wildcard origin, browsers should actually block this configuration entirely. However, some Actix versions may not enforce this correctly, creating a security gap where authenticated requests from malicious origins could be processed.
Real-world exploitation often involves phishing sites that trick users into visiting malicious pages, which then make API calls to vulnerable Actix endpoints using the user's authenticated session. The wildcard CORS policy allows these cross-origin requests to succeed, potentially exposing user data or enabling account takeover.
Actix-Specific Detection
Detecting CORS wildcard misconfigurations in Actix applications requires both manual code review and automated scanning. The vulnerability manifests through specific patterns in your Actix codebase that can be identified systematically.
Manual detection starts with searching for these patterns in your Actix source code:
// Search for these patterns:
cors::Cors::permissive()
Cors::default().allowed_origin("*")
Cors::default().supports_credentials() combined with wildcard origins
Using grep or your IDE's search functionality:
grep -r "Cors::permissive" src/
grep -r "allowed_origin.*\"*\"" src/
grep -r "supports_credentials" src/ | grep -A5 "allowed_origin"
Automated detection with middleBrick specifically targets Actix applications by scanning running instances. middleBrick's CORS security checks include:
- Wildcard origin detection: Tests if the API accepts requests from any origin
- Credentials support analysis: Verifies if
Access-Control-Allow-Credentials: trueis enabled with wildcard origins - Preflight request handling: Checks how the API responds to OPTIONS requests
- Exposed headers analysis: Identifies overly permissive header exposure
Using middleBrick CLI to scan an Actix API:
npx middlebrick scan https://your-actix-api.com
# Or install globally:
npm install -g middlebrick
middlebrick scan https://your-actix-api.com
The scan results will show CORS-specific findings with severity levels. For wildcard origin issues, middleBrick typically reports:
CORS Security - High Severity
- Issue: Wildcard origin (*) allowed
- Risk: Any website can make cross-origin requests
- Recommendation: Restrict origins to specific domains
middleBrick also analyzes OpenAPI specifications if available, cross-referencing documented CORS policies with actual runtime behavior. This is particularly useful for Actix applications using actix-openapi or similar spec generation tools.
For CI/CD integration, add middleBrick to your Actix project's workflow:
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run middleBrick Scan
run: |
npx middlebrick scan https://staging.your-actix-app.com
continue-on-error: true
This ensures CORS misconfigurations are caught before deployment to production environments.
Actix-Specific Remediation
Remediating CORS wildcard vulnerabilities in Actix requires replacing permissive configurations with strict, origin-specific policies. The most secure approach is to explicitly define allowed origins based on your application's requirements.
Basic remediation for a single allowed origin:
use actix_web::{web, App, HttpServer, HttpResponse};
use actix_cors::Cors;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(
Cors::default()
.allowed_origin("https://your-trusted-domain.com")
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
.allowed_headers(vec!["Content-Type", "Authorization"])
.max_age(3600)
)
.service(web::resource("/api").route(web::get().to(|| HttpResponse::Ok())))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
For applications with multiple trusted origins, use the allowed_origins method:
use actix_cors::Cors;
let cors = Cors::default()
.allowed_origins(vec![
"https://app1.yourcompany.com",
"https://app2.yourcompany.com",
"https://admin.yourcompany.com"
])
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"])
.allowed_headers(vec![
"Content-Type",
"Authorization",
"X-Requested-With"
])
.supports_credentials() // Only if you need to send cookies
.max_age(3600);
Dynamic origin validation for Actix applications with variable subdomains:
use actix_web::dev::ServiceRequest;
use actix_cors::Cors;
fn build_cors() -> Cors {
Cors::new()
.validate_origin(|origin| {
// Only allow specific subdomains
if let Ok(url) = origin.to_string().parse::() {
if url.host_str().map(|h| h.ends_with(".yourcompany.com")).unwrap_or(false) {
return true;
}
}
false
})
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"])
.allowed_headers(vec!["Content-Type", "Authorization"])
.supports_credentials()
.max_age(3600)
}
For Actix applications using the actix-web-actors or WebSocket endpoints, ensure CORS is properly configured for upgrade requests:
use actix_web::{get, App, HttpServer, HttpResponse, Error};
use actix_cors::Cors;
use tokio_tungstenite::tungstenite::Message;
#[get("/ws")]
async fn websocket() -> Result {
// WebSocket handler implementation
Ok(HttpResponse::Ok().finish())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(
Cors::default()
.allowed_origin("https://your-trusted-domain.com")
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"])
.allowed_headers(vec!["Content-Type", "Authorization"])
.supports_credentials()
.finish()
)
.service(web::resource("/ws").route(web::get().to(websocket)))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Testing your CORS configuration after remediation is crucial. Use curl to verify:
# Test preflight OPTIONS request
curl -X OPTIONS https://your-actix-api.com/api \
-H "Origin: https://your-trusted-domain.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type"
# Test actual request
curl https://your-actix-api.com/api \
-H "Origin: https://your-trusted-domain.com" \
-H "Content-Type: application/json"
Finally, integrate middleBrick into your development workflow to catch CORS regressions:
# Continuous monitoring with middleBrick Pro
middlebrick monitor https://your-actix-api.com \
--schedule=daily \
--alert=slack://hooks.slack.com/services/... \
--fail-if-severity=high
This ensures your Actix CORS policies remain secure as your application evolves.
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 |