Header Injection in Adonisjs
How Header Injection Manifests in Adonisjs
Header injection in Adonisjs occurs when user-controlled input is improperly handled in HTTP response headers, allowing attackers to manipulate header values and potentially execute attacks like HTTP response splitting, XSS via headers, or cache poisoning. In Adonisjs applications, this vulnerability often emerges through several specific patterns.
The most common manifestation appears when user input flows directly into response headers without proper validation. Consider an Adonisjs controller that echoes back request headers:
async showProfile({ response, request }) {
const customHeader = request.header('X-Custom-Header')
response.header('X-Profile-Info', customHeader)
return response.json({ success: true })
}This code is vulnerable because customHeader could contain newline characters (
) that break the HTTP response structure. An attacker could send:
X-Custom-Header: normal-value
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
<script>alert('XSS')</script>The response would be split, causing the browser to execute the injected script.
Another Adonisjs-specific pattern involves middleware that constructs headers from request parameters. Many Adonisjs applications use middleware to add authentication or tracking headers:
async handle({ request, response }, next) {
const userId = request.input('user_id')
response.header('X-User-ID', userId)
await next()
}If userId contains malicious content, it can manipulate response headers. Adonisjs's implicit response handling makes this particularly dangerous because the framework automatically finalizes responses.
Header injection also appears in Adonisjs through improper handling of URL parameters in redirect responses. Consider:
async redirectWithHeader({ response }) {
const url = request.input('url')
response.redirect(url)
response.header('X-Redirect-Info', url)
return response
}An attacker could manipulate the url parameter to include newline characters, affecting subsequent headers.
Adonisjs's template engine can also contribute to header injection when dynamic content flows into meta tags or other header-like structures rendered in HTML. While not a traditional HTTP header, these can be exploited for similar attacks when rendered in email templates or API responses.
Adonisjs-Specific Detection
Detecting header injection in Adonisjs requires both manual code review and automated scanning. The framework's structure creates specific patterns that security tools should target.
Manual detection starts with reviewing controller methods that handle user input and set response headers. Look for patterns where request data flows directly to response.headers() without sanitization. In Adonisjs, search for:
response.header()
response.append()
response.safeHeader()
ctx.response.set()Pay special attention to middleware that processes authentication tokens, user IDs, or any request-derived values. Adonisjs's middleware structure means these transformations happen early in the request lifecycle, giving attackers more opportunities to manipulate the final response.
middleBrick's API security scanner specifically detects header injection vulnerabilities in Adonisjs applications through several mechanisms. The scanner tests for newline character injection by sending payloads containing sequences to parameters that influence header values. It then analyzes the response to detect HTTP response splitting or header manipulation.
For Adonisjs applications, middleBrick examines:
- Controller methods that set custom headers from request data
- Middleware that constructs authentication or tracking headers
- Redirect responses that incorporate user input
- Template rendering that outputs to meta tags or similar structures
- API endpoints that echo back request headers
The scanner's LLM/AI security module also checks for prompt injection in Adonisjs applications that use AI features, as these can sometimes interact with header processing in unexpected ways.
middleBrick's OpenAPI spec analysis is particularly valuable for Adonisjs applications, as it can cross-reference your API definitions with runtime findings. If your Adonisjs application uses OpenAPI specifications, middleBrick will validate that the documented headers match the actual behavior and identify discrepancies that might indicate security issues.
Running middleBrick against your Adonisjs API is straightforward:
npx middlebrick scan https://your-adonisjs-app.com/apiThe scanner will provide a security score and detailed findings, including any header injection vulnerabilities discovered during the 5-15 second scan.
Adonisjs-Specific Remediation
Remediating header injection in Adonisjs requires a defense-in-depth approach that combines input validation, output encoding, and framework-specific protections.
The first line of defense is input validation. Adonisjs provides robust validation through its Validator module. Always validate and sanitize user input before using it in headers:
import { schema } from '@adonisjs/core/validator'
const headerSchema = schema.create({
customHeader: schema.string.optional({
escape: true,
trim: true
}, [
rules.blacklist(['\r', '\n', '\0'])
])
})
async showProfile({ response, request }) {
const payload = await request.validate(headerSchema)
const customHeader = payload.customHeader || 'default-value'
response.header('X-Profile-Info', customHeader)
return response.json({ success: true })
}This validation ensures that newline characters and other dangerous sequences are removed before being used in headers.
For middleware that constructs headers from user data, implement strict validation:
import { schema } from '@adonisjs/core/validator'
const userIdSchema = schema.string({ escape: true }, [
rules.regex(/^[a-zA-Z0-9_-]{1,32}$/)
])
export class UserIdHeaderMiddleware {
async handle({ request, response }, next) {
const userId = request.input('user_id', 'anonymous')
try {
const validatedId = await request.validate({
schema: userIdSchema,
data: { user_id: userId }
})
response.header('X-User-ID', validatedId.user_id)
} catch (error) {
response.header('X-User-ID', 'invalid')
}
await next()
}
}Adonisjs's built-in response methods provide some protection, but explicit validation is still necessary. The framework's response.safeHeader() method exists but doesn't prevent all forms of header injection, so don't rely on it alone.
For redirect responses, implement strict URL validation:
import { schema } from '@adonisjs/core/validator'
const urlSchema = schema.string({ trim: true }, [
rules.url({ schemes: ['https'] }),
rules.notRegex(/[
]/)
])
async redirectWithHeader({ response }) {
const url = request.input('url', '/default')
try {
const validatedUrl = await request.validate({
schema: urlSchema,
data: { url }
})
response.redirect(validatedUrl.url)
} catch (error) {
response.redirect('/error')
}
return response
}Consider implementing a Content Security Policy (CSP) header as an additional defense layer. Adonisjs makes this straightforward:
response.header('Content-Security-Policy', "default-src 'self'; script-src 'self'")
For applications that use Adonisjs's view engine, ensure that any dynamic content rendered in meta tags or similar structures is properly escaped. The framework's template engine provides automatic escaping, but verify that this is enabled in your configuration.
middleBrick's continuous monitoring can help verify that your remediations remain effective over time. After implementing fixes, rescan your API to ensure the security score improves and that no new header injection vulnerabilities have been introduced.
Frequently Asked Questions
How can I test if my Adonisjs application is vulnerable to header injection?
Does Adonisjs provide built-in protection against header injection?
response.safeHeader() method exists but has limitations. Developers must implement proper input validation and sanitization, particularly for user-controlled data that flows into response headers. middleBrick can help identify gaps in your application's header injection defenses.