Sql Injection in Adonisjs with Mutual Tls
Sql Injection in Adonisjs with Mutual Tls
AdonisJS is a Node.js web framework that encourages an ORM-based approach via Lucid ORM. When combined with mutual TLS (mTLS), the application enforces client certificate verification at the transport layer. While mTLS strengthens authentication and encryption between clients and the server, it does not automatically protect against SQL injection at the application layer. A false sense of security can emerge when teams assume encrypted, authenticated channels eliminate injection risks.
SQL injection in AdonisJS typically arises when dynamic values are concatenated into SQL queries or when query builder conditions are constructed from untrusted input. Even with mTLS ensuring that only clients presenting valid certificates can reach the endpoint, an authenticated client can still send malicious payloads if input validation and parameterized queries are not consistently applied. Common vulnerable patterns include using raw queries with string interpolation or improperly binding values in where clauses.
Consider an endpoint that retrieves a user by username over an mTLS-secured connection:
const User = use('App/Models/User')
const { username } = request.get()
const user = await User.query().whereRaw('username = \'${username}\'').first()
In this example, even though the request arrived over a mutually authenticated TLS channel, the whereRaw usage introduces a classic SQL injection vector. An attacker who has obtained a valid client certificate (e.g., via compromise or provisioning abuse) can supply username values such as ' OR 1=1 -- to manipulate the query logic.
Another scenario involves dynamic ordering or pagination parameters that are directly interpolated into raw queries. With mTLS in place, the identity of the client is verified, but the application still needs to sanitize and validate inputs to prevent injection. The framework’s schema-based validation can help, but it must be applied rigorously to all incoming fields that affect query construction.
Key takeaways: mTLS protects transport integrity and client identity, but it does not sanitize inputs or enforce safe query construction. SQL injection remains possible in AdonisJS when untrusted data is incorporated into SQL statements without parameterization, regardless of the presence of mutual TLS.
Mutual Tls-Specific Remediation in Adonisjs
Remediation focuses on secure query practices combined with proper mTLS configuration in AdonisJS. The framework does not have built-in automatic SQL sanitization; developers must use parameterized queries and strict validation. Below are concrete steps and code examples to secure AdonisJS applications while retaining mTLS for client authentication.
1. Use parameterized queries with Lucid ORM
Always use bound parameters with the query builder instead of string concatenation. Lucid supports named bindings safely:
const User = use('App/Models/User')
const { username } = request.get()
// Safe: parameterized query
const user = await User.query().where('username', username).first()
2. Validate and sanitize all inputs
Apply validation rules to incoming data before using it in queries. For example, enforce alphanumeric usernames with a strict regex:
const validation = use('Validator')
const rules = {
username: 'required|regex:^[a-zA-Z0-9_]+$'
}
const { username } = await request.validate(rules)
const user = await User.query().where('username', username).first()
3. Configure mTLS in AdonisJS via Node.js HTTPS server options
When running AdonisJS with its built-in server or a custom HTTPS setup, specify certificate verification options. The following example creates an HTTPS server that requires client certificates:
const fs = require('fs')
const https = require('https')
const { Ignitor } = require('@adonisjs/ignitor')
const serverOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-cert.pem'),
ca: fs.readFileSync('path/to/ca-cert.pem'),
requestCert: true,
rejectUnauthorized: true
}
new Ignitor(require('@adonisjs/fold'))
.appRoot(__dirname)
.startHttpServer(serverOptions)
.then(() => {
console.log('HTTPS server with mTLS running on port 3333')
})
.catch(error => {
console.error('Failed to start server:', error)
})
4. Combine mTLS with route-level authentication checks
Even with mTLS, implement additional checks to ensure the authenticated certificate maps to an authorized user or role. You can inspect the client certificate details in a request hook:
// In a middleware or route handler
const cert = request.$request.socket.getPeerCertificate()
if (!cert.subject || !cert.subject.CN) {
throw new Error('Client certificate missing common name')
}
// Map CN or serial to user permissions, then proceed with safe queries
By combining parameterized queries, strict input validation, and properly configured mTLS options, AdonisJS applications can mitigate SQL injection risks while maintaining strong transport-layer authentication.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |