Injection Flaws in Adonisjs
How Injection Flaws Manifest in Adonisjs
Injection flaws in Adonisjs applications typically occur when user-supplied data is incorporated into SQL queries, command execution, or template rendering without proper sanitization. These vulnerabilities allow attackers to execute malicious SQL statements, run arbitrary commands on the server, or inject malicious content into rendered templates.
The most common injection vector in Adonisjs is SQL injection through the Lucid ORM. While Lucid provides protection against many injection scenarios, developers can inadvertently bypass these protections:
const Database = use('Database')
// Vulnerable: Direct string interpolation
const username = request.input('username')
const users = await Database.query().from('users')
.whereRaw(`username = '${username}'`)This code is vulnerable because the username parameter is directly interpolated into the SQL string, allowing an attacker to inject arbitrary SQL. An attacker could supply admin' OR '1'='1 to bypass authentication or extract sensitive data.
Another common Adonisjs injection scenario involves command injection through the Node.js child_process module:
const { exec } = require('child_process')
// Vulnerable: Command injection
const filePath = request.input('file')
exec(`ls -la ${filePath}`, (err, stdout, stderr) => {
console.log(stdout)
})Here, an attacker could supply ./; rm -rf / to execute arbitrary commands on the server.
Template injection is another concern in Adonisjs applications using the Edge templating engine. While Edge has built-in protections, improper use can lead to XSS vulnerabilities:
// Vulnerable: Unsanitized template rendering
const userInput = request.input('message')
return view.render('message', { message: userInput })If the message template doesn't properly escape user input, this could lead to cross-site scripting attacks.
Adonisjs-Specific Detection
Detecting injection flaws in Adonisjs applications requires a combination of static analysis and dynamic testing. middleBrick's API security scanner can identify many injection vulnerabilities through its comprehensive black-box testing approach.
For SQL injection detection, middleBrick tests common injection patterns against your API endpoints. It analyzes the application's response patterns to identify potential vulnerabilities:
# Scan an Adonisjs API endpoint
middlebrick scan https://api.yourapp.com/usersThe scanner tests for classic SQL injection patterns like:
- Single quote termination (
' OR '1'='1) - Boolean-based injection (
' AND 1=1) - Time-based injection (
' WAITFOR DELAY '0:0:5'--) - Union-based injection (
' UNION SELECT NULL--)
middleBrick also checks for command injection vulnerabilities by testing special characters and command separators:
# Test for command injection
middlebrick scan https://api.yourapp.com/execute --test-command-injectionFor template injection, the scanner examines API responses for signs of unescaped user input and tests for XSS payloads:
# Check for XSS vulnerabilities
middlebrick scan https://api.yourapp.com/messages --test-xssAdonisjs developers can also use the built-in validator to check for dangerous patterns:
const { validate } = use('Validator')
const rules = {
username: 'required|alpha_numeric',
file: 'required|regex:\/^[a-zA-Z0-9_.-]+\/$/'
}
const validation = await validate(request.all(), rules)
if (validation.fails()) {
return response.badRequest(validation.messages())
}This validation helps prevent injection by restricting input to safe character sets.
Adonisjs-Specific Remediation
Remediating injection flaws in Adonisjs requires a defense-in-depth approach. The first line of defense is using parameterized queries with Lucid's query builder:
// Secure: Parameterized query
const username = request.input('username')
const users = await Database.query().from('users')
.where('username', username)This approach automatically escapes user input, preventing SQL injection. For more complex queries, use Lucid's raw query method with parameter binding:
const userId = request.input('id')
const query = 'SELECT * FROM users WHERE id = ?'
const users = await Database.raw(query, [userId])For command injection prevention, avoid using exec with user input entirely. If you must execute commands, use the execFile method with strict validation:
const { execFile } = require('child_process')
async function listDirectory(dir) {
// Validate directory path strictly
if (!dir.match(/^\/[a-zA-Z0-9_.-\/]+$/)) {
throw new Error('Invalid directory path')
}
return new Promise((resolve, reject) => {
execFile('ls', ['-la', dir], (err, stdout, stderr) => {
if (err) return reject(err)
resolve(stdout)
})
})
}Adonisjs's Edge templating engine provides automatic escaping by default. Ensure you're using the {{ }} syntax for HTML escaping:
{{ message }}
{{{ message }}}
For additional security, implement Content Security Policy headers in your Adonisjs application:
// app/Http/kernel.js
const globalMiddleware = [
'Adonis/Core/BodyParser',
'Adonis/Core/Cors',
'App/Middleware/ContentSecurityPolicy'
]Create a Content Security Policy middleware:
// app/Middleware/ContentSecurityPolicy.js
'use strict'
class ContentSecurityPolicy {
async handle({ response }, next) {
response.header('Content-Security-Policy',
"default-src 'self'; script-src 'self' 'nonce-...'; style-src 'self'")
await next()
}
}
module.exports = ContentSecurityPolicyFinally, integrate middleBrick's continuous scanning into your development workflow to catch injection vulnerabilities early:
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm install -g middlebrick
- run: middlebrick scan https://staging.yourapp.com/apiThis GitHub Action will scan your staging API on every pull request, ensuring injection flaws are caught before production deployment.
Frequently Asked Questions
How does middleBrick detect SQL injection in Adonisjs applications?
Can middleBrick detect command injection in Adonisjs route handlers?
child_process usage patterns that might indicate vulnerable code.