Hallucination Attacks in Adonisjs
How Hallucination Attacks Manifest in Adonisjs
Hallucination attacks in Adonisjs applications exploit the framework's dynamic model binding and implicit data handling to manipulate API responses. These attacks occur when an API endpoint returns data that wasn't explicitly requested, often through model relationships or eager loading configurations.
In Adonisjs, the most common manifestation involves the fetch and fetchOrCreate methods on model relationships. Consider this vulnerable Adonisjs controller:
class UserController {
async show({ params }) {
const user = await User.find(params.id)
await user.load('profile') // Eager loads profile data
return user
}
}
An attacker can exploit this by manipulating the request to include relationship parameters:
GET /api/users/1?include=profile.posts.comments
Without proper authorization checks, this could expose posts and comments data belonging to the user's profile, even though the original endpoint only intended to return basic user information.
Adonisjs's Lucid ORM makes this particularly dangerous because model relationships are resolved automatically. The framework's serialize method includes all loaded relationships by default:
const user = await User.find(1)
await user.load('profile')
const json = user.toJSON() // Includes profile data automatically
Another Adonisjs-specific vulnerability arises from implicit model casting. When using transformers or serializers, sensitive fields might be exposed if not explicitly excluded:
class UserTransformer {
getDefault({ user }) {
return {
id: user.id,
name: user.name,
email: user.email // Should be excluded for non-admin roles
}
}
}
The framework's middleware pipeline can also introduce hallucination risks. A missing authorization check in a global middleware might allow unauthorized access to related data:
// VULNERABLE: Missing role check
async function (request, response, next) {
const user = await auth.getUser()
request.user = user
await user.load('profile') // Loads data for all requests
await next()
}
Adonisjs-Specific Detection
Detecting hallucination attacks in Adonisjs requires examining both the application code and runtime behavior. The framework's structure makes certain patterns particularly susceptible to these attacks.
Code-level detection focuses on these Adonisjs-specific patterns:
// Scan for vulnerable patterns
// 1. Eager loading without authorization
const user = await User.find(id)
await user.load('profile') // Check if authorization is missing
// 2. Implicit serialization
const user = await User.query().preload('profile')
return response.json(user) // Check if sensitive data is included
// 3. Transformer vulnerabilities
class UserTransformer {
getDefault({ user }) {
return {
// Check for missing field exclusions
email: user.email,
phone: user.phone
}
}
}
middleBrick's API security scanner specifically detects Adonisjs hallucination vulnerabilities by analyzing runtime API responses. The scanner tests for:
- Unauthorized relationship data exposure through parameter manipulation
- Implicit model serialization including sensitive fields
- Transformer configurations that expose data based on request context
- Middleware that loads data without proper authorization checks
The scanner's LLM/AI security module also tests for prompt injection vulnerabilities that could manipulate Adonisjs's dynamic query building:
// middleBrick active testing probes
// Test for parameter manipulation
GET /api/users/1?include=profile.posts.comments
// Test for transformer manipulation
POST /api/users with malicious payload that alters transformer behavior
middleBrick's OpenAPI analysis is particularly effective for Adonisjs applications because it can detect when the runtime behavior deviates from the documented API contract, a common indicator of hallucination vulnerabilities.
Adonisjs-Specific Remediation
Remediating hallucination attacks in Adonisjs requires leveraging the framework's built-in security features and following strict data exposure principles.
The primary defense is explicit field selection and relationship filtering:
class UserController {
async show({ params, response }) {
const user = await User
.query()
.where('id', params.id)
.select('id', 'name', 'email') // Only allowed fields
.first()
if (!user) {
return response.status(404).json({ error: 'User not found' })
}
// Explicitly control relationships
const profile = await user.related('profile').query()
.select('id', 'bio') // Only allowed profile fields
return response.json({
id: user.id,
name: user.name,
email: user.email,
profile: profile ? {
id: profile.id,
bio: profile.bio
} : null
})
}
}
For transformer-based responses, implement role-based field exclusion:
class UserTransformer {
getDefault({ user, auth }) {
const data = {
id: user.id,
name: user.name
}
// Only include email for authorized users
if (auth.user && auth.user.id === user.id) {
data.email = user.email
}
// Only include admin fields for admins
if (auth.user && auth.user.isAdmin) {
data.created_at = user.created_at
data.last_login = user.last_login
}
return data
}
}
Implement strict relationship authorization in Adonisjs middleware:
// auth/authorizeRelationships.js
async function authorizeRelationships(request, response, next) {
const user = await auth.getUser()
const allowedIncludes = ['profile'] // Whitelist relationships
const includeParams = request.qs.include?.split(',') || []
const unauthorizedIncludes = includeParams.filter(
include => !allowedIncludes.includes(include)
)
if (unauthorizedIncludes.length > 0) {
return response.status(403).json({
error: 'Unauthorized relationship access',
denied: unauthorizedIncludes
})
}
await next()
}
Use Adonisjs's query scope feature to encapsulate authorization logic:
// app/Models/User.js
class User extends BaseModel {
static withAllowedRelationships(query, allowedIncludes = ['profile']) {
return query.preload('profile', (profileQuery) => {
profileQuery.select('id', 'bio') // Only allowed fields
})
}
}
// Controller usage
const user = await User
.query()
.withAllowedRelationships()
.where('id', params.id)
.first()
Related CWEs: llmSecurity
| CWE ID | Name | Severity |
|---|---|---|
| CWE-754 | Improper Check for Unusual or Exceptional Conditions | MEDIUM |
Frequently Asked Questions
How does Adonisjs's Lucid ORM contribute to hallucination attack risks?
load, preload) automatically includes related data, and toJSON() serializes all loaded relationships by default, making it easy to accidentally return more data than intended.