Denial Of Service in Adonisjs
How Denial Of Service Manifests in Adonisjs
Denial of Service (DoS) attacks against Adonisjs applications exploit the framework's synchronous processing model and middleware chain execution. Unlike asynchronous frameworks that can handle multiple requests concurrently, Adonisjs processes requests sequentially through its middleware pipeline, making it vulnerable to resource exhaustion when attackers flood endpoints with malformed or computationally expensive requests.
The most common Adonisjs DoS vectors target the framework's validation middleware and database query execution. When an attacker submits requests with deeply nested JSON structures or extremely large payloads, Adonisjs's body parser can consume significant memory before validation fails. For example, a POST request with a payload like { "a": { "b": { "c": ... } } } with thousands of nested levels can cause the JSON parser to allocate memory proportional to the nesting depth, potentially exhausting available heap space.
Adonisjs's Lucid ORM creates another attack surface through N+1 query vulnerabilities. When controllers retrieve related models without proper eager loading, a single endpoint request can generate dozens or hundreds of database queries. An attacker exploiting this can trigger expensive database operations that consume connection pool resources. Consider this vulnerable pattern:
async index ({ request }) {
const users = await User.all()
const enriched = await Promise.all(
users.rows.map(async user => {
return {
...user.toJSON(),
posts: await user.posts().fetch(),
comments: await user.comments().fetch()
}
})
)
return enriched
}
This endpoint generates N+1 queries where N is the number of users, creating a perfect DoS condition when combined with pagination bypass attacks.
Rate limiting bypasses represent another critical Adonisjs DoS vector. The framework's built-in rate limiter uses in-memory storage by default, which can be circumvented through IP spoofing or distributed attacks. When the limiter relies on Redis or other external stores, misconfiguration can lead to memory leaks or connection exhaustion. Attackers often combine this with slowloris-style attacks, keeping connections open with partial requests to exhaust the server's connection pool.
Adonisjs-Specific Detection
Detecting DoS vulnerabilities in Adonisjs requires understanding the framework's request lifecycle and middleware execution. middleBrick's black-box scanning approach is particularly effective for Adonisjs applications because it tests the actual runtime behavior without requiring source code access or authentication credentials.
middleBrick identifies Adonisjs-specific DoS patterns through several automated checks. The scanner tests for JSON parser vulnerabilities by sending requests with deeply nested structures and measuring response times and error patterns. For Lucid ORM vulnerabilities, middleBrick analyzes endpoint behavior with varying payload sizes and tracks database query counts through timing analysis and error responses that reveal query execution patterns.
The scanner's rate limiting tests specifically target Adonisjs's middleware implementation. middleBrick sends rapid-fire requests to authenticated and unauthenticated endpoints, measuring how the framework handles request queuing and connection management. The tool also tests for slowloris vulnerabilities by sending incomplete requests and observing connection timeout behavior.
middleBrick's LLM/AI security module adds another layer of detection for Adonisjs applications that use AI features. The scanner tests for excessive agency in AI-powered endpoints, which can create DoS conditions when AI models consume disproportionate computational resources. This includes detecting endpoints that make external API calls or execute code based on AI responses.
Configuration analysis through OpenAPI spec scanning helps identify DoS risks in Adonisjs applications. middleBrick resolves all $ref references in the API specification and cross-references them with runtime findings. This reveals endpoints with missing rate limiting, inadequate input validation, or exposed administrative functions that could be exploited for DoS attacks.
Adonisjs-Specific Remediation
Securing Adonisjs applications against DoS attacks requires a multi-layered approach that addresses both framework-specific vulnerabilities and general security best practices. The first layer of defense involves implementing proper input validation and payload size limits using Adonisjs's built-in middleware.
// app/Http/kernel.ts
import { Application } from '@adonisjs/core'
import { cuid } from '@adonisjs/core/sink'
const app = Application.instance
const globalMiddleware = [
'Adonis/Core/BodyParser',
{
name: 'Adonis/Core/RateLimiter',
config: {
driver: 'memory',
remaining: 100,
expires: 900,
keyGenerator: async (request) => {
const ip = request.ip()
const url = request.url()
return `${ip}:${url}`
}
}
}
]
const namedMiddleware = {
validateSize: 'App/Middleware/ValidateSize'
}
For JSON parsing protection, create a custom middleware that limits nesting depth and payload size:
// app/Middleware/ValidateSize.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ValidateSize {
async handle (ctx: HttpContextContract, next: () => Promise) {
const maxBytes = 1024 * 1024 // 1MB
const maxDepth = 10
const contentLength = ctx.request.headers['content-length']
if (contentLength && parseInt(contentLength) > maxBytes) {
return ctx.response.badRequest('Payload too large')
}
const body = ctx.request.all()
if (this.hasExcessiveNesting(body, maxDepth)) {
return ctx.response.badRequest('Excessive JSON nesting')
}
await next()
}
private hasExcessiveNesting(obj: any, maxDepth: number, currentDepth = 0): boolean {
if (currentDepth >= maxDepth) return true
if (obj === null || typeof obj !== 'object') return false
return Object.values(obj).some(value =>
this.hasExcessiveNesting(value, maxDepth, currentDepth + 1)
)
}
}
Database query optimization is critical for preventing N+1 DoS vulnerabilities. Adonisjs's Lucid ORM provides eager loading to eliminate these issues:
// app/Controllers/Http/UserController.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import Post from 'App/Models/Post'
export default class UserController {
async index ({ request }: HttpContextContract) {
const { page = 1, limit = 20 } = request.qs()
const users = await User
.query()
.preload('posts', (query) => {
query.select('id', 'title', 'user_id')
})
.preload('comments', (query) => {
query.select('id', 'content', 'user_id')
})
.paginate(page, limit)
return users
}
}
Implementing Redis-based rate limiting provides better protection than the default memory driver:
// config/rateLimiter.ts
import { cuid } from '@adonisjs/core/sink'
export default () => {
return {
driver: 'redis',
connection: 'local',
remaining: 100,
expires: 900,
keyGenerator: async (request) => {
const ip = request.ip()
const url = request.url()
return `${ip}:${url}`
}
}
}
For production deployments, combine Adonisjs middleware with reverse proxy protections like Nginx rate limiting and Cloudflare's DDoS protection. The framework's middleware chain executes after these external protections, providing defense in depth against DoS attacks.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |