Cors Wildcard in Adonisjs with Api Keys
Cors Wildcard in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability
A wildcard CORS policy (Access-Control-Allow-Origin: *) combined with API key authentication in an AdonisJS application can unintentionally expose protected endpoints to any origin. When the CORS configuration permits all origins, browsers allow cross-origin requests to include credentials and custom headers, including the API key, if the server also opts into credentialed requests. This combination can enable a malicious site to make authenticated requests on behalf of a user or service that has inadvertently exposed the key via browser-based clients, effectively bypassing origin-based isolation.
In AdonisJS, this typically occurs when the CORS configuration in start/cors.ts sets origin: ['*'] while the application also validates API keys via headers (e.g., X-API-Key) and does not restrict which origins are allowed to present those keys. Even though API keys protect the endpoint from unauthenticated callers, the wildcard origin allows any webpage to include the key in a request, which can be embedded in malicious scripts or loaded via <script> or fetch if credentials are permitted. The browser’s same-origin policy is circumvented because CORS grants cross-origin access, and the API key is treated as a credential, exposing the endpoint to CSRF-like scenarios where the key is leaked or abused.
The risk is compounded if the API key is passed in headers rather than cookies, because a wildcard CORS policy with allowCredentials: true can lead to situations where the browser sends the key to third-party origins. AdonisJS applications that use JWTs or session-based auth alongside API keys may also inadvertently expose tokens through CORS preflight responses, allowing attackers to enumerate valid endpoints or harvest keys via insecure logging or error messages. This aligns with OWASP API Security Top 10 categories such as Broken Object Level Authorization (BOLA) and Improper Inventory Management, where overly permissive CORS rules expand the attack surface.
For example, an AdonisJS service that uses middleware to check for a valid X-API-Key might still respond to preflight requests with Access-Control-Allow-Origin: * and Access-Control-Allow-Headers: X-API-Key. A malicious site hosted on https://evil.com can then issue a cross-origin fetch that includes the header, and if the server fails to validate the origin against a denylist or an allowlist, the request proceeds as authenticated. This pattern is detectable in scans that flag CORS misconfigurations alongside authentication mechanisms, emphasizing the need for strict origin definitions rather than wildcards when API keys are in play.
Api Keys-Specific Remediation in Adonisjs — concrete code fixes
To remediate the interaction between CORS wildcard and API keys in AdonisJS, update the CORS configuration to specify exact origins instead of using a wildcard. Combine this with strict validation of the Origin header against an allowlist and ensure that credentials are only allowed for trusted origins. Below are concrete code examples for secure configuration in AdonisJS.
First, modify start/cors.ts to define allowed origins explicitly and disable wildcard usage:
import { cors } from '@ioc:Adonis/Addons/Cors'
export default cors({
enabled: true,
origin: ['https://trusted-frontend.com', 'https://app.yourdomain.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
headers: ['Content-Type', 'Authorization', 'X-API-Key'],
allowCredentials: true,
})
Next, implement middleware to validate the incoming origin against the allowlist before setting CORS headers. This prevents reflected origins and ensures that only known domains can make authenticated requests:
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ApiKeyMiddleware {
public async handle(ctx: HttpContextContract, next: () => Promise) {
const requestOrigin = ctx.request.header('origin')
const allowedOrigins = ['https://trusted-frontend.com', 'https://app.yourdomain.com']
if (requestOrigin && allowedOrigins.includes(requestOrigin)) {
ctx.response.header('Access-Control-Allow-Origin', requestOrigin)
} else {
ctx.response.status(403).send({ error: 'CORS origin not allowed' })
return
}
if (ctx.request.header('x-api-key') !== process.env.API_KEY) {
ctx.response.status(401).send({ error: 'Invalid API key' })
return
}
await next()
}
}
Additionally, ensure that API keys are not logged or exposed in error responses, and consider rotating keys regularly. For applications that also serve browser-based clients, use short-lived tokens or additional CSRF protections alongside API keys, even when origins are restricted. These measures reduce the risk of key leakage via CORS-related attacks and align with secure deployment practices.
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
Can a wildcard CORS policy be safe if API keys are not used?
Does allowing credentials with a wildcard CORS policy always cause a browser error?
withCredentials is true, so using Access-Control-Allow-Origin: * with credentials is invalid and prevents the request from succeeding.