Cors Wildcard in Adonisjs with Jwt Tokens
Cors Wildcard in Adonisjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
In AdonisJS, using a wildcard CORS_ORIGIN (e.g., *) while protecting routes with JWT-based authentication can unintentionally expose authenticated endpoints to any origin. When the CORS configuration permits all origins, preflight requests succeed from any domain, allowing a browser to send authenticated requests that include cookies or Authorization headers. If your application relies on JWTs passed via cookies (e.g., using jwt:guard with cookie-based persistence), the wildcard enables a malicious site to make cross-origin authenticated calls on behalf of a victim who has an active session. The JWT mechanism itself is not misconfigured, but the CORS policy removes the same-origin enforcement that would otherwise prevent unauthorized origins from leveraging the user’s credentials.
Consider an AdonisJS app with a typical JWT guard configured in start/hash.js:
const { body } = require('@adonisjs/fold')
const { HttpException } = require('@adonisjs/generic-exceptions')
module.exports = {
guard: 'jwt',
providers: {
JwtProvider: () => {
const { Jwt } = use('Adonis/Addons/Adonisjs-Jwt')
return new Jwt()
},
CookieProvider: () => {
const { Cookie } = use('Adonis/Addons/Adonisjs-Cookie')
return new Cookie()
}
}
}
If the CORS configuration in start/cors.js uses a wildcard origin while the application sets JWTs in cookies:
const Env = use('Env')
module.exports = {
enabled: true,
origin: Env.get('CORS_ORIGIN', '*'),
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
allowHeaders: 'authorization, content-type',
allowCredentials: true
}
The combination allows any origin to perform authenticated requests via the browser, provided the server sets Access-Control-Allow-Credentials: true and the JWT is stored in a cookie. An attacker can craft a page that issues requests to your API endpoints; the browser automatically includes the cookie, and the server treats the call as authenticated. This bypasses same-origin protections and can lead to unauthorized data access or actions, even though JWT validation itself is working as intended.
middleBrick scans detect this pattern during black-box testing by checking whether authenticated endpoints are reachable from arbitrary origins while credentials are present. The tool correlates CORS settings with authentication mechanisms such as JWT guards and flags configurations that permit credentialed cross-origin requests without restricting origins. This cross-referencing of spec definitions with runtime behavior helps highlight the exposure without implying automatic remediation.
Jwt Tokens-Specific Remediation in Adonisjs — concrete code fixes
To secure AdonisJS applications that use JWTs stored in cookies, restrict CORS origins to known, trusted domains and avoid wildcard origins when credentials are involved. If you must support multiple frontends, enumerate origins explicitly or use a controlled allowlist. Below are concrete configuration and code examples.
1. Update the CORS origin to a specific list instead of *. In start/cors.js:
const Env = use('Env')
module.exports = {
enabled: true,
origin: [
'https://app.yourdomain.com',
'https://admin.yourdomain.com'
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
allowHeaders: 'authorization, content-type',
allowCredentials: true
}
2. If you rely on environment-based configuration, ensure that production never defaults to *. For example, in .env:
CORS_ORIGIN=https://app.yourdomain.com,https://admin.yourdomain.com
And in start/cors.js, parse the list appropriately (AdonisJS does not natively split comma-separated strings, so implement a small helper or set directly as an array in code for safety).
3. Keep JWT guards intact but ensure tokens are not unnecessarily exposed to cross-origin contexts. Example JWT guard setup in start/hash.js remains appropriate:
const { HttpException } = require('@adonisjs/generic-exceptions')
module.exports = {
guard: 'jwt',
providers: {
JwtProvider: () => {
const { Jwt } = use('Adonis/Addons/Adonisjs-Jwt')
return new Jwt()
},
CookieProvider: () => {
const { Cookie } = use('Adonis/Addons/Adonisjs-Cookie')
return new Cookie()
}
}
}
4. For additional safety, avoid storing sensitive JWTs in cookies when CORS is complex; instead, use Authorization headers with strict CORS. If cookies are required, ensure HttpOnly and Secure flags are set, and consider SameSite attributes to mitigate CSRF:
Cookie.set('token', jwtToken, {
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/'
})
5. Validate origins programmatically in middleware if dynamic rules are needed, rejecting requests where the Origin header does not match allowed patterns. This complements CORS settings and provides defense-in-depth for authenticated endpoints.
middleBrick’s continuous monitoring in the Pro plan can alert you when CORS configurations drift toward permissive settings after deployments, helping maintain a secure posture without manual audits. The GitHub Action can fail builds if a scan detects a wildcard origin in authenticated contexts, integrating security checks directly into your CI/CD pipeline.
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 |