Out Of Bounds Read in Adonisjs with Jwt Tokens
Out Of Bounds Read in Adonisjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
An Out Of Bounds Read occurs when a data access operation reads memory or data beyond the intended allocation boundary. In AdonisJS applications that use JWT tokens for authentication, this often arises when token payload parsing, signature verification, or claims validation does not properly constrain the length or type of data being read from buffers, arrays, or strings.
Consider a scenario where an endpoint decodes a JWT and directly indexes into a user-provided array or string without validating bounds. For example, extracting a claim by a dynamic index derived from token data can lead to reading memory outside the intended buffer if the index is not strictly validated. This is especially risky when the token payload contains numeric values used as offsets or lengths, and those values are attacker-controlled.
In AdonisJS, JWT handling is commonly done via the jwt provider (e.g., use('jwt')). If the application uses custom logic to parse or transform the token payload — for instance, reading nested claims using a key derived from other claims — an unchecked or oversized payload can expose sensitive data or cause erratic behavior. Even when using standard jwt.verify or jwt.use calls, improper handling of malformed tokens, unexpected claim structures, or large payloads can trigger underlying parser routines to perform out of bounds memory reads, potentially leaking internal data or causing denial of service.
Real-world patterns that increase risk include:
- Using numeric claim values as array indices without range checks (e.g.,
payload.roles[Number(sub)]). - Parsing untrusted input that influences buffer allocations or string slicing operations during token processing.
- Chaining multiple transforms where one stage produces an out-of-range value consumed by another stage, leading to unsafe reads in downstream logic.
Because JWT tokens often carry sensitive authorization data, an out of bounds read can inadvertently expose private claims or internal state. The AdonisJS application may not directly crash, but the behavior becomes unpredictable, and in some runtime conditions, adjacent memory could be read and reflected in logs or error messages, aiding further attacks.
middleBrick’s LLM/AI Security checks specifically test for scenarios where token-driven logic might lead to unsafe data access patterns, including active prompt injection and system prompt leakage that could coax the application into revealing token-derived indices or structures. These checks complement the 12 security scans — including Authentication, Input Validation, and Unsafe Consumption — that evaluate how JWT handling interacts with the broader attack surface.
Jwt Tokens-Specific Remediation in Adonisjs — concrete code fixes
To mitigate Out Of Bounds Read risks when using JWT tokens in AdonisJS, enforce strict schema validation and avoid dynamic indexing based on token data. Always validate numeric claims used as indices, and use fixed-length structures where possible.
1. Validate and sanitize claims before use
Do not trust claims that dictate array sizes or indices. Explicitly check types and ranges.
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
const tokenSchema = schema.create({
required: true,
shape: {
sub: schema.string(),
roles: schema.array.optional().members(schema.number()),
permissions: schema.array.optional().members(schema.number()),
},
})
export default class AuthController {
public async verify({ request, auth }: HttpContextContract) {
const payload = request.only(['token'])
// Validate token structure before decoding
const validated = schema.validateSync(tokenSchema, payload)
if (validated.fails()) {
throw new Error('Invalid token payload')
}
const token = request.input('token')
const decoded = await auth.use('jwt').verify(token)
// Safe: roles is an array of numbers, but we still guard access
const roleIndex = decoded.roles?.[0]
if (typeof roleIndex === 'number' && Number.isFinite(roleIndex) && roleIndex >= 0) {
// Proceed safely
}
}
}
2. Avoid dynamic indexing from token data
Replace dynamic claim-based indexing with static mappings or whitelisted selectors.
// Unsafe: using token-derived index
const userRole = decoded.roles[decoded.roleIndex] // Risk if roleIndex is untrusted
// Safe: map using a controlled lookup
const roleMap = {
admin: 'Administrator',
user: 'Standard User',
}
const roleKey = decoded.roleKey in roleMap ? decoded.roleKey : 'user'
const roleName = roleMap[roleKey]
3. Use structured payloads and limit nesting
Keep JWT payloads flat and avoid deeply nested structures that require runtime traversal based on token content.
const simpleTokenPayload = {
sub: 'user-123',
role: 'admin',
scope: 'api.read api.write',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600,
}
middleBrick’s CLI tool can be used to scan your AdonisJS endpoints and flag unsafe JWT handling patterns. Run middlebrick scan <url> to get structured findings, including those tied to Authentication and Input Validation checks. For teams needing continuous oversight, the Pro plan provides ongoing monitoring and integrates with GitHub Actions to fail builds if risky token usage is detected in pull requests.