HIGH sql injectionadonisjsmutual tls

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 IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does mutual TLS prevent SQL injection in AdonisJS?
No. Mutual TLS secures transport and client identity but does not sanitize inputs. SQL injection must be prevented through parameterized queries and strict input validation.
What is a safe way to query user data in AdonisJS with mTLS enabled?
Use parameterized queries with Lucid ORM, validate inputs with a strict schema, and configure the HTTPS server with requestCert and rejectUnauthorized set to true.