HIGH identification failuresadonisjsjwt tokens

Identification Failures in Adonisjs with Jwt Tokens

Identification Failures in Adonisjs with Jwt Tokens

Identification failures occur when an API cannot reliably determine the identity of a requestor. In AdonisJS, combining the framework’s route/handler model with JWT tokens for authentication can expose identification weaknesses if token validation, payload extraction, or subject mapping is not handled consistently.

AdonisJS typically uses the auth provider and guards (e.g., jwt) to authenticate requests. When JWT tokens are used, the framework validates the token’s signature and, if valid, attaches a user model (or a subset) to the auth context. Identification failures arise when:

  • The token payload lacks a stable, unique subject (e.g., missing or ambiguous sub claim).
  • Token validation succeeds but the user referenced by the token does not exist or is inactive (e.g., deleted or disabled accounts).
  • The identity derived from the token does not map correctly to application-specific identifiers used for access control (e.g., using database IDs vs. usernames).
  • Token claims are not normalized or enriched consistently across services, leading to mismatched identities in microservice calls.

These issues can allow an attacker to masquerade as another user if the system relies solely on token validity without verifying the existence and status of the associated identity. For example, an attacker could copy a valid JWT issued to a low-privilege user and present it to an endpoint that checks only token validity, not whether the referenced user is authorized for the requested resource.

In AdonisJS, this often surfaces in guarded routes where the controller assumes auth.user is populated and trustworthy. If the identity lookup fails silently or returns a stale user object, the route may inadvertently operate under an incorrect identity. Additionally, if the JWT is issued with a broad scope but the application layer does not re-validate scopes against the current identity context, privilege confusion can occur.

OpenAPI/Swagger analysis can highlight missing or inconsistent security schemes for JWT-based endpoints. When spec definitions reference a securitySchemes entry of type http with bearer format, but the implementation does not enforce token validation or identity checks, the runtime behavior may diverge from the documented contract. Cross-referencing spec definitions with runtime findings helps detect cases where authentication is declared but identification is weak or absent.

Consider a scenario where an endpoint expects a JWT with a sub claim that maps to a user ID, but the handler queries the database using a non-unique field (e.g., email) that may be missing or altered. This mismatch can lead to incorrect identification and authorization decisions.

Jwt Tokens-Specific Remediation in Adonisjs

Remediation focuses on ensuring that JWT tokens are validated, decoded, and mapped to a reliable, verifiable identity within AdonisJS. Follow these steps to strengthen identification:

  1. Enforce strict token validation: Use AdonisJS auth guards to validate JWT signatures and expiration. Do not accept tokens without verifying their integrity.
  2. Normalize the subject claim: Ensure the JWT includes a stable, unique sub claim (e.g., a user UUID or numeric ID) and that this claim is used as the primary identity key.
  3. Re-lookup the identity on each request: In the authenticated handler, resolve the user from the database using the sub claim rather than trusting metadata attached by the token.
  4. Check account status: Confirm the user is active and not suspended or deleted before granting access.
  5. Use consistent identifiers: Map token claims to application identifiers consistently across services to avoid mismatches.

Example: Validating and using JWT in an AdonisJS controller

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { schema, rules } from '@ioc:Adonis/Core/Validator'

export default class UserController {
  public async me({ auth, request }: HttpContextContract) {
    // Ensure the guard enforces JWT validation
    const user = await auth.authenticate()

    // Re-lookup the user to ensure identity is current and active
    const currentUser = await User.findOrFail(user.id)

    if (!currentUser.isActive) {
      throw new Error('Account is inactive') // or handle accordingly
    }

    return { id: currentUser.id, email: currentUser.email }
  }
}

Example: Defining a JWT guard in start/auth.ts

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { TokenGuard } from '@ioc:Adonis/Addons/Auth'

export const guards = {
  jwt: {
    driver: 'jwt',
    provider: 'users',
    tokenProvider: { type: 'custom', token: { type: 'access' } },
    // Ensure tokens are validated on each request
  },
}

Example: Valid token payload with stable subject

{
  "sub": "usr_123e4567-e89b-12d3-a456-426614174000",
  "iat": 1717000000,
  "exp": 1717003600,
  "email": "[email protected]",
  "roles": ["user"]
}

By combining runtime validation with explicit identity resolution, you reduce the risk of identification failures. The dashboard can be used to track security scores over time, while the CLI allows scanning endpoints from the terminal. For CI/CD integration, the GitHub Action can fail builds if risk scores drop below your chosen threshold, and the MCP Server enables scanning APIs directly from AI coding assistants.

Frequently Asked Questions

What should the 'sub' claim contain in a JWT for AdonisJS?
Use a stable, unique identifier such as a UUID or numeric user ID that maps directly to your user records and does not change over time.
Does AdonisJS re-validate user status on every request when using JWT?
Not automatically. You must explicitly re-lookup the user and check fields like isActive in your handler to ensure the identity is current and authorized.