HIGH auth bypassadonisjsopenid connect

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 IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I test my AdonisJS OIDC integration for authentication bypass issues?
Use an external scanner that supports OpenID Connect security checks, such as middleBrick, which runs authenticated-like tests including state and nonce validation and token verification to detect misconfigurations that can lead to auth bypass.
What should I do if the OIDC callback does not receive a valid ID token in AdonisJS?
Treat it as an authentication failure. Do not create a session. Log the event, return an unauthorized response, and ensure your integration validates token presence, signature, issuer, audience, and nonce before establishing any local session.