Session Fixation in Adonisjs with Api Keys
Session Fixation in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability
Session fixation occurs when an application assigns a user a session identifier before authentication and fails to rotate it after login. In AdonisJS, this risk can be amplified when API keys are used for authentication but session management is not consistently invalidated or segregated from key-based flows.
AdonisJS does not impose a session store by default; developers commonly use cookie-based sessions via the @adonisjs/session package. If an endpoint accepts both session cookies and API keys, and does not enforce a clean authentication boundary, an attacker can fixate a session ID on a victim (e.g., via URL or referrer leakage) and then trick the victim into authenticating with that session. Because the API key may be treated as a secondary credential, the server might still associate the fixed session with the authenticated identity, leading to unauthorized access.
Consider an AdonisJS route that authenticates via API key but also relies on session cookies for supplementary claims (such as CSRF exemption or UI state). A typical vulnerable pattern:
// routes.ts
Route.get('/profile', async ({ auth, session }) => {
const apiKey = request.headers().get('x-api-key')
// Vulnerable: session may already be set before key validation
if (apiKey === process.env.ADMIN_KEY) {
session.put('role', 'admin') // session fixation risk if session pre-exists
return { role: session.get('role') }
}
throw new Error('Unauthorized')
})
In this setup, an attacker can craft a link that includes a known session cookie (or sets one via Set-Cookie in a cross-site context if lax protections are in place). When the victim visits the link and authenticates with the API key, the server may retain the attacker’s session ID while elevating privileges. Because the API key itself is static and not rotated per session, the mapping between key and session becomes predictable, enabling privilege escalation or unauthorized data access.
The LLM/AI Security checks in middleBrick specifically test for scenarios where authentication mechanisms like API keys interact with session handling, exposing logic flaws that could lead to token or session hijacking. These tests simulate injection attempts and analyze whether outputs inadvertently expose identifiers or credentials.
Api Keys-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on strict separation of authentication factors, session rotation after successful key validation, and ensuring API keys are not used as implicit session identifiers.
1. Rotate the session after key-based authentication to eliminate fixation. In AdonisJS, call session.regenerate() after validating the API key to assign a fresh session ID.
// routes.ts
Route.post('/login', async ({ request, auth, session }) => {
const apiKey = request.headers().get('x-api-key')
if (apiKey !== process.env.ADMIN_KEY) {
return response.unauthorized()
}
// Rotate session to prevent fixation
await session.regenerate()
session.put('role', 'admin')
return { role: session.get('role') }
})
2. Avoid storing sensitive claims in the session when API keys are the primary credential. Prefer stateless validation for key-only endpoints and keep sessions opt-in for UI flows.
// routes.ts — key-only endpoint without session dependency
Route.get('/data', async ({ request }) => {
const apiKey = request.headers().get('x-api-key')
if (apiKey !== process.env.DATA_KEY) {
return response.unauthorized()
}
// Stateless response, no session interaction
return { data: 'sensitive dataset' }
})
3. Enforce strict key storage and scope. Rotate keys periodically, avoid embedding user identifiers in keys, and use middleware to validate keys against a secure store (e.g., environment variables or a vault). For multi-tenant scenarios, scope keys to specific contexts and avoid cross-context session sharing.
// middleware/api-key.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export async function validateApiKey({ request, response }: HttpContextContract) {
const key = request.headers().get('x-api-key')
if (!key || key !== process.env.SERVICE_KEY) {
response.unauthorized()
}
}
middleBrick’s CLI can be used to verify that your endpoints do not leak session identifiers when API keys are present. Run middlebrick scan <url> to detect authentication and authorization misconfigurations, including improper session handling alongside key-based flows.