Auth Bypass in Adonisjs with Openid Connect
Auth Bypass in Adonisjs with Openid Connect — how this specific combination creates or exposes the vulnerability
AdonisJS is a Node.js web framework that does not include authentication logic by default; developers add packages to handle protocols such as OpenID Connect (OIDC). When integrating OIDC, it is common to use libraries that implement the OAuth 2.0 Authorization Code flow with an identity provider (IdP). If the integration does not strictly validate the OAuth 2.0 state parameter and does not verify ID tokens according to OIDC specifications, an authentication bypass can occur.
One typical pattern vulnerable to bypass is relying only on the presence of a user profile in the OIDC callback without verifying the ID token signature, issuer, audience, or nonce. An attacker who can influence the redirect URI or the state parameter might be able to redirect the user to a malicious callback that completes the login without a valid identity assertion. In AdonisJS, this can happen if the route handling the OIDC callback trusts session data or query parameters instead of validating the token-bound context. For example, an attacker might induce a login by sending a victim to a URL like /auth/callback?state=attacker_controlled and relying on the application to treat the callback as legitimate when it should enforce strict token validation.
Another bypass risk arises from misconfigured session management after OIDC authentication. If the application creates a session or sets an authentication cookie before verifying the token’s scope and claims, an attacker who can predict or reuse a state value might establish a session without a genuine authentication event. This is especially risky when the middleware that assigns user identity does not re-validate the OIDC token on each sensitive request, allowing horizontal privilege escalation (BOLA/IDOR) where one user accesses another’s data by manipulating identifiers.
OpenID Connect-specific checks are essential: validate the ID token signature using the provider’s JWKS, verify the issuer (iss), audience (aud), and nonce, and ensure the authorization code is exchanged only for a properly authenticated user. In AdonisJS, failing to enforce these checks means the framework’s route handlers may treat an unauthenticated or unverified callback as a logged-in session, effectively bypassing intended access controls.
Openid Connect-Specific Remediation in Adonisjs — concrete code fixes
To securely integrate OpenID Connect in AdonisJS, validate tokens and strictly manage state. Use a maintained OIDC client library that supports discovery, JWKS signature verification, and standard claims validation. Below is a concise, realistic example using openid-client with AdonisJS-style route handling.
import { Issuer, generators } from 'openid-client';
import { HttpContext } from '@adonisjs/core/types';
export default class OidcController {
async authorize(ctx: HttpContext) {
const client = await Issuer.discover('https://your-identity-provider.com');
const oidcClient = new client({
client_id: process.env.OIDC_CLIENT_ID,
client_secret: process.env.OIDC_CLIENT_SECRET,
redirect_uris: [process.env.OIDC_CALLBACK_URL],
response_types: ['code'],
});
const state = generators.randomState();
const nonce = generators.randomNonce();
ctx.session.put('oidc_state', state);
ctx.session.put('oidc_nonce', nonce);
const authorizationUrl = oidcClient.authorizationUrl({
scope: 'openid profile email',
state,
nonce,
});
return ctx.redirect(authorizationUrl);
}
async callback(ctx: HttpContext) {
const { code, state } = ctx.request.qs;
const sessionState = ctx.session.get('oidc_state');
const sessionNonce = ctx.session.get('oidc_nonce');
if (!sessionState || state !== sessionState) {
ctx.response.unauthorized({ error: 'invalid_state' });
return;
}
const client = await Issuer.discover('https://your-identity-provider.com');
const oidcClient = new client({
client_id: process.env.OIDC_CLIENT_ID,
client_secret: process.env.OIDC_CLIENT_SECRET,
redirect_uris: [process.env.OIDC_CALLBACK_URL],
response_types: ['code'],
});
const tokenSet = await oidcClient.callback(ctx.request.url, { code }, {
nonce: sessionNonce,
});
// Validate claims explicitly
if (tokenSet.claims().iss !== process.env.OIDC_ISSUER) {
ctx.response.unauthorized({ error: 'invalid_issuer' });
return;
}
if (tokenSet.claims().aud !== process.env.OIDC_CLIENT_ID) {
ctx.response.unauthorized({ error: 'invalid_audience' });
return;
}
if (tokenSet.claims().nonce !== sessionNonce) {
ctx.response.unauthorized({ error: 'invalid_nonce' });
return;
}
// Establish session only after successful token validation
ctx.session.put('user', {
sub: tokenSet.claims().sub,
email: tokenSet.claims().email,
});
ctx.response.redirect('/dashboard');
}
}
Key remediation practices specific to OIDC in AdonisJS:
- Always verify the state parameter stored in the session against the callback parameter to prevent CSRF-induced login bypass.
- Always verify the nonce to mitigate replay attacks across authentication flows.
- Validate the ID token signature using the provider’s JWKS and ensure the issuer and audience match your configuration.
- Do not create a session or set authentication cookies until token validation succeeds.
- Ensure the redirect URI used in the authorization request is registered exactly with the IdP, including protocol and path, to prevent redirect-based bypasses.
- Enforce PKCE by using a code verifier and challenge to protect against authorization code interception.
By combining strict token validation with secure session handling, AdonisJS applications can avoid OIDC-related authentication bypasses and ensure that identity assertions are trustworthy before establishing user sessions.
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 |