Jwt Misconfiguration in Adonisjs with Api Keys
Jwt Misconfiguration in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability
JWT misconfiguration in AdonisJS becomes especially risky when API keys are used alongside or in place of session-based authentication. AdonisJS does not enforce a default authentication scheme; developers explicitly choose packages such as @adonisjs/auth or integrate JWT via jwt provider. When API keys—typically static bearer tokens meant for service-to-service or client identification—are combined with JWTs, confusion about which mechanism is authoritative can lead to insecure defaults.
A common misconfiguration is enabling JWT guards without properly isolating or scoping them to intended routes. If a route intended for API key access is mistakenly guarded by a JWT strategy, unauthenticated callers may bypass intended key validation. Conversely, if JWTs are accepted in contexts that should require a rotating API key, the system may inadvertently accept unsigned or poorly validated tokens. For example, failing to set ignoreExpiration to false or not validating the iss (issuer) and aud (audience) claims can allow tokens issued for one service to be accepted by another.
Another specific risk is storing or logging JWTs as if they were API keys. API keys are often treated as long-lived secrets; JWTs, especially when not encrypted, may contain sensitive claims. If a JWT is accidentally logged or cached alongside API key identifiers, it can expose user or scope information. Additionally, weak signing algorithms—such as using none or HS256 with a shared secret across services—can allow attackers to forge tokens that masquerade as valid API credentials. AdonisJS applications that fail to explicitly define token algorithms or to rotate signing keys increase the likelihood that a compromised key or algorithm weakness leads to privilege escalation or unauthorized access across endpoints that should be protected by distinct API key boundaries.
Middleware misalignment compounds these issues. AdonisJS allows route-level middleware to enforce authentication. If a developer applies JWT middleware to routes that should validate API keys only, unauthenticated requests may be incorrectly permitted. For example, a route defined as GET /admin/users that relies on a JWT guard but should instead require a pre-shared API key could be accessed by any party able to obtain or guess a valid JWT from another context. This is a classic case of mismatched authentication factors, where the combination of JWT and API keys without strict route segregation creates an unintended attack surface.
Finally, the interplay with OpenAPI/Swagger specifications can amplify misconfiguration. When generating specs, developers might document API key locations in headers while JWTs are handled separately in securitySchemes. If the runtime configuration does not strictly enforce the documented flow—such as accepting JWTs in an Authorization: Bearer header where only API keys are permitted—an attacker can probe endpoints with malformed or stolen tokens. middleBrick’s LLM/AI Security checks and spec analysis help detect such inconsistencies by correlating declared schemes with runtime behavior, highlighting where JWT misconfiguration intersects with API key usage.
Api Keys-Specific Remediation in Adonisjs — concrete code fixes
To remediate JWT misconfiguration when using API keys in AdonisJS, enforce strict separation of concerns between authentication mechanisms and validate all inputs and configurations explicitly.
1. Isolate API key validation to dedicated routes
Ensure routes requiring API keys do not inherit JWT guards. Define a custom middleware that checks for a valid API key in headers or environment variables, and apply it selectively.
// start/middleware/apiKeyValidator.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ApiKeyValidator {
public async handle(ctx: HttpContextContract, next: () => Promise<void>) {
const apiKey = ctx.request.header('X-API-Key')
const expectedKey = ctx.app.config.get('apiKeys.primary')
if (!apiKey || apiKey !== expectedKey) {
ctx.response.status(401).send({ error: 'Unauthorized: Invalid API key' })
return
}
await next()
}
}
Register the middleware in start/kernel.ts and apply it only to routes that require API key access, avoiding any JWT guard inheritance.
2. Enforce strict JWT configuration when used separately
If JWTs are used for a different subset of routes, explicitly configure the provider to reject unsigned tokens and enforce issuer/audience validation.
// config/jwt.ts
import { jwtConfig } from '@ioc:Adonis/Addons/Jwt'
const jwt: jwtConfig = {
guards: {
api_jwt: {
driver: 'jwt',
secret: () => import('App/Helpers/jwtSecret'),
issuer: 'my-adonis-app',
audience: 'api.my-adonis-app.com',
ignoreExpiration: false,
algorithms: ['HS256'],
},
},
}
export default jwt
Ensure that algorithms are explicitly set and that the secret is rotated periodically. Avoid using none or allowing weak symmetric keys across services.
3. Validate and scope tokens and keys at runtime
When both mechanisms coexist, validate scopes and claims rigorously. For API keys used in server-side calls, treat them as opaque strings and avoid embedding JWTs within them. For JWTs, verify not only signature but also standard claims to prevent token misuse across boundaries.
// Example runtime validation in a controller
import { schema } from '@ioc:Adonis/Core/Validator'
export class TokenController {
public async validateJwt() {
const payload = await auth.use('api_jwt').authenticate()
// Additional custom checks, e.g., scope or context
if (!payload.scopes || !payload.scopes.includes('read:users')) {
throw new Error('Insufficient scope')
}
return payload
}
}
Use environment-specific configuration to ensure keys and secrets differ across development, staging, and production. middleBrick’s dashboard can track configuration drift and highlight when JWT and API key settings overlap incorrectly.
4. Secure storage and logging practices
Never log API keys or JWTs in plain text. Sanitize request and response logs to remove sensitive authorization headers. Rotate API keys and signing secrets on a defined schedule and monitor for reuse across services.
5. Testing and verification
Verify that routes expecting API keys return 401 when accessed with JWTs, and vice versa. Use the CLI to scan endpoints and confirm that authentication guards are applied as documented. The CLI can be invoked as:
middlebrick scan https://api.example.com/v1
For CI/CD integration, the GitHub Action can enforce that risk scores do not regress, ensuring that any future changes do not re-introduce JWT/key misalignment.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |