Cors Wildcard in Axum with Api Keys
Cors Wildcard in Axum with Api Keys — how this specific combination creates or exposes the vulnerability
Axum is a Rust web framework where CORS configuration and authorization mechanisms such as API keys are composed at runtime. A Cors Wildcard combined with API key enforcement creates a dangerous mismatch between origin validation and credential handling. In CORS, a wildcard origin (*) permits requests from any source. When API keys are used as the authorization mechanism and are passed via headers (e.g., x-api-key), browsers enforce CORS preflight checks. If the server responds with Access-Control-Allow-Origin: * and also exposes headers containing key material or allows credentials, the browser may permit a cross-origin script to read responses that should be isolated.
This combination exposes a classic authorization bypass pattern where origin-based restrictions are effectively neutralized. An attacker can craft a webpage hosted on a malicious domain that sends requests with a valid API key (e.g., obtained via misconfiguration or social engineering). The browser includes the key in the request header because the endpoint expects x-api-key. If the server does not validate the Origin header against a strict allowlist and echoes back a wildcard, the attacker’s JavaScript can read the response, bypassing the intended same-origin protection.
Additionally, during preflight requests, if the server returns Access-Control-Allow-Methods that include unsafe methods and Access-Control-Allow-Headers includes x-api-key, the wildcard origin permits any site to probe allowed methods and headers. This can facilitate cross-origin request forgery where the attacker iterates through methods to infer behavior. In the context of middleBrick’s security checks, this pattern maps to BOLA/IDOR and Property Authorization failures because the resource ownership or authorization context is not validated in conjunction with the CORS policy.
Real-world parallels include findings where misconfigured CORS with wildcard origins allowed unauthorized cross-origin access to admin endpoints. For example, a server might return 200 OK with * and expose headers containing API keys, enabling an attacker to harvest credentials via a simple script. This violates the principle of least privilege and separation of concerns between authorization and CORS. middleBrick’s checks for Data Exposure and Unsafe Consumption highlight such misconfigurations by correlating runtime responses with spec-defined security schemes.
In Axum, developers often use middleware to handle CORS and API key extraction. If the CORS layer is configured before authentication and uses a wildcard, while the authentication layer expects keys, the order and interaction become critical. The framework does not inherently prevent this mismatch; it is the developer’s responsibility to ensure that permissive CORS rules do not undermine token-based authorization. OWASP API Top 10’s Broken Object Level Authorization (BOLA) and the broader category of Improper Asset Management are relevant here, as the endpoint’s exposure is a control failure.
To validate this during a scan, middleBrick sends requests with varied origins and inspects response headers for wildcard allowances alongside the presence of API key requirements. If a public endpoint echoes back an API key in error messages or logs, this is flagged as Data Exposure. The scanner also tests whether preflight responses permit cross-origin credentials, which would indicate a high-risk configuration.
Api Keys-Specific Remediation in Axum — concrete code fixes
Remediation focuses on aligning CORS policy with authorization requirements. API keys should never be exposed to wildcard origins. In Axum, implement a strict CORS policy that mirrors the set of trusted origins and ensures that credentials are not inadvertently allowed. Use the cors middleware with explicit configuration, and apply it after authentication or with awareness of middleware ordering.
Below is a syntactically correct Axum example demonstrating secure composition. The CORS layer allows only specific origins and does not expose headers containing keys. API key validation occurs before routing, ensuring that unauthorized requests are rejected early.
use axum::{
async_trait,
extract::Extension,
middleware::Next,
response::Response,
routing::get,
Router,
};
use cors::CorsLayer;
use headers::HeaderMapExt;
use std::net::SocketAddr;
struct ApiKeyValidator;
#[async_trait]
impl axum::extract::FromRequest<S> for ApiKeyValidator
where
S: Send + Sync,
{
type Rejection = Response;
async fn from_request(req: axum::extract::Request, next: Next<S>) -> Result<Self::Rejection, Self> {
let api_key = req.headers().get("x-api-key");
match api_key {
Some(key) if key == "your-secure-key" => Ok(ApiKeyValidator),
_ => Err(axum::http::StatusCode::UNAUTHORIZED.into_response()),
}
}
}
async fn handler() -> &'static str {
"secure data"
}
#[tokio::main]
async fn main() {
let cors = CorsLayer::new()
.allow_origin(vec!["https://trusted.example.com".parse().unwrap()].into_iter().collect())
.allow_headers(vec![headers::AUTHORIZATION, headers::CONTENT_TYPE].into_iter().collect())
.allow_methods(vec![axum::http::Method::GET].into_iter().collect())
.expose_headers(vec![].into_iter().collect()); // Do not expose API keys
let app = Router::new()
.route("/data", get(handler))
.layer(cors)
.layer(axum::middleware::from_fn_with_extractor(|Extension(_), ApiKeyValidator, Next| async move {
Ok(Next::run().await)
}));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
In this example, the CORS layer uses a concrete list of origins instead of a wildcard. The allow_origin method restricts requests to trusted domains. The expose_headers is intentionally empty to prevent leaking API keys in response headers. API key validation is implemented as an extractor, ensuring that only requests with a valid key proceed to the handler. Middleware ordering places CORS before authentication so that preflight requests are handled without granting unauthorized methods, but the extractor ensures that even valid preflight responses do not expose credentials.
For production, rotate keys regularly and avoid hardcoding them. Use environment variables or a secure vault. middleBrick’s CLI can be used to verify that the endpoint no longer responds with wildcard origins or exposed keys. The Pro plan’s continuous monitoring can alert on regressions in CORS configuration, ensuring that future changes do not reintroduce this class of vulnerability.
When integrating with CI/CD, the GitHub Action can enforce that any change to CORS or auth configuration does not introduce a wildcard origin or insecure header exposure. This shifts detection left, reducing the window of exposure. The MCP Server allows developers to scan API definitions directly from their IDE, catching such issues before deployment.
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 |