Auth Bypass in Adonisjs with Session Cookies
Auth Bypass in Adonisjs with Session Cookies — how this specific combination creates or exposes the vulnerability
Auth bypass in AdonisJS when using session cookies typically arises from gaps in session validation, insecure cookie attributes, or missing authorization checks on sensitive routes. AdonisJS relies on session identifiers stored in cookies to maintain authentication state; if these cookies are not protected and validated correctly, an attacker can manipulate or reuse them to gain unauthorized access.
One common pattern is storing only a user identifier in the session cookie without a server-side binding to a session record or token version. If an attacker can guess or obtain a valid user ID (e.g., through user enumeration or predictable IDs), they can craft a session cookie and authenticate as that user. This is a BOLA/IDOR-style issue where object-level authorization is not enforced on the session lookup itself.
Insecure cookie attributes exacerbate the risk. If the Secure flag is not set, cookies can be transmitted over unencrypted channels; without HttpOnly, client-side scripts may read the cookie enabling XSS-based theft; and without SameSite set to Lax or Strict, the browser may send the cookie in cross-site requests, enabling CSRF-based session hijacking. AdonisJS allows fine-grained control over these attributes via the session configuration file, and omitting them weakens the overall authentication boundary.
Middleware that only checks for the presence of a session cookie, rather than validating its integrity and scope, can also introduce bypasses. For example, an authenticated route that skips permission checks for "own resources" without verifying that the resource truly belongs to the requesting user enables IDOR. Attackers can modify resource identifiers in the request to access other users’ data. This intersects with BFLA when elevated permissions are inferred from a tampered or replayed session without re-authorization.
Real-world attack patterns mirror findings from scans run by tools like middleBrick, which tests authentication and authorization surfaces. For instance, an unauthenticated scan might flag endpoints where a session cookie is accepted without verifying scope or binding to a server-side session state. Such findings align with OWASP API Security Top 10 categories, particularly Broken Object Level Authorization and Security Misconfiguration. middleBrick’s authentication and BOLA/IDOR checks highlight these classes of issues by correlating cookie handling with endpoint behavior, producing prioritized findings with remediation guidance in the dashboard and CLI reports.
Session Cookies-Specific Remediation in Adonisjs — concrete code fixes
Remediation centers on hardening session cookies and enforcing strict authorization checks on every request. Below are concrete configurations and code examples for AdonisJS that address the three dimensions of the issue.
1. Secure session cookie configuration
Update config/session.ts to enforce secure defaults. Use SameSite, HttpOnly, and Secure flags appropriate for your deployment (use true for Secure in production with HTTPS).
import { sessionConfig } from '@ioc:Adonis/Addons/Session'
const sessionConfig: sessionConfig = {
driver: 'cookie',
cookie: {
name: 'auth_session',
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
domain: undefined,
maxAge: 1000 * 60 * 60 * 8, // 8 hours
},
adapter: {
disk: {},
},
}
export default sessionConfig
2. Bind session to a server-side token/salt and validate on each request
Avoid storing only the user ID in the session. Bind the session to a rotating token stored in the database and validated on each authenticated request. In the login handler, after verifying credentials, generate a random token, persist it, and set it in the session.
import { DateTime } from 'luxon'
import { randomBytes } from 'crypto'
import User from 'App/Models/User'
export default class SessionsController {
async login({ request, auth, response }) {
const { email, password } = request.all()
const user = await User.verifyCredentials(email, password)
// Generate a server-side bound token
const sessionToken = randomBytes(32).toString('hex')
user.sessionToken = sessionToken
await user.save()
const session = auth.use('web').getSession()
session.put('userId', user.id)
session.put('sessionToken', sessionToken)
await session.save()
return response.redirect().toRoute('dashboard')
}
}
On each request, middleware should verify that the session token matches the user’s stored token. If not, force re-authentication.
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
export async function ensureSessionToken(ctx: HttpContextContract) {
const session = ctx.session
const userId = session.get('userId')
const tokenInSession = session.get('sessionToken')
if (!userId || !tokenInSession) {
ctx.response.unauthorized('Session invalid')
return
}
const user = await User.find(userId)
if (!user || user.sessionToken !== tokenInSession) {
ctx.response.unauthorized('Session invalid or expired')
return
}
// Optionally rotate token periodically
if (Math.random() < 0.05) {
const newToken = require('crypto').randomBytes(32).toString('hex')
user.sessionToken = newToken
await user.save()
session.put('sessionToken', newToken)
await session.save()
}
}
3. Enforce authorization on every resource access
Never rely solely on session presence to authorize access to a resource. Always scope queries to the requesting user and verify ownership or permissions server-side.
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Document from 'App/Models/Document'
export default class DocumentsController {
async show({ params, auth }) {
const document = await Document.query()
.where('id', params.id)
.where('user_id', auth.user?.id)
.preload('owner')
.firstOrFail()
return document
}
}
Combine this with route-level middleware that calls ensureSessionToken and verifies scoping to prevent BOLA/IDOR and BFLA. middleBrick’s checks for authentication, BOLA/IDOR, and BFLA will surface missing validations and cookie misconfigurations, giving you prioritized remediation steps in reports and the dashboard.
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 |