Type Confusion in Adonisjs with Mutual Tls
Type Confusion in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability
Type confusion in an AdonisJS application using mutual TLS (mTLS) arises when the runtime misinterprets the expected type of a value—often due to loosely validated request inputs or deserialized data—leading to unauthorized method execution or property access. mTLS authenticates both client and server using X.509 certificates, which ensures transport-layer identity and encryption, but it does not validate the semantic correctness of application-level data structures. If an endpoint accepts JSON or form data and binds it directly to models or uses it to determine behavior (e.g., selecting a service class or casting a string to an integer), an attacker can supply values that cause the runtime to treat an object as an incorrect type.
Consider an AdonisJS route that receives a certificate-based identity (via mTLS) and also a user-controlled type field to decide which processor to invoke. If the type value is used in a switch or polymorphic association without strict validation, an attacker might pass a numeric ID where an object is expected, or a string that maps to an unintended class. Because mTLS ensures the connection is encrypted and the client is authenticated, developers may assume request data is trustworthy, inadvertently relaxing input checks. This trust boundary mismatch enables type confusion: the runtime may call methods on the wrong object, interpret a string as a function, or follow incorrect prototype chains, potentially leading to information disclosure or unauthorized actions.
Real-world examples include using Object.prototype.toString to infer types on attacker-controlled objects or relying on implicit coercion in equality checks. In AdonisJS controllers, passing unchecked request parameters into service constructors or repository methods can trigger these issues, especially when combined with features like schema-based casting that may not enforce strict type boundaries. The mTLS layer does not mitigate these logic flaws; it only authenticates peers. Therefore, even with mTLS enforcing identity, insufficient type guards, missing schema validation, and unchecked polymorphic deserialization remain common root causes.
For instance, an endpoint using an OpenAPI spec with $ref definitions might bind request bodies to models that assume certain types. If the runtime receives mismatched types due to missing validation, the binding logic may misinterpret structures, leading to prototype pollution or incorrect method dispatch. This is detectable by middleBrick’s checks for Input Validation and Property Authorization, which highlight places where type expectations are not enforced. The scanner cross-references the OpenAPI/Swagger spec (2.0, 3.0, 3.1) with runtime findings to surface inconsistencies between declared schemas and actual handling, emphasizing the need for strict type narrowing regardless of mTLS presence.
Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes
To remediate type confusion in AdonisJS while using mutual TLS, enforce strict input validation and type guards at the application layer, independent of transport security. Use Joi or AdonisJS schema validation to define exact shapes for incoming data, and avoid relying on implicit casting or untrusted client-supplied type discriminators. Below are concrete code examples demonstrating secure practices with mTLS in AdonisJS.
Example 1: Strict schema validation with mTLS identity
Assume an endpoint that uses client certificates to identify users but still validates request payloads rigorously.
'use strict'
const Joi = require('joi')
const { validate } = use('Validator')
class UserController {
async updateProfile ({ request, auth }) {
// mTLS provides auth.user from certificate; we still validate input
const schema = Joi.object({
displayName: Joi.string().max(255),
preferences: Joi.object({
theme: Joi.string().valid('light', 'dark').default('light'),
notifications: Joi.boolean()
}).unknown(false)
}).unknown(false)
const payload = request.only(['displayName', 'preferences'])
const validation = await validate(payload, schema)
if (validation.fails()) {
return response.badRequest(validation.messages())
}
const user = auth.user
user.displayName = payload.displayName
user.preferences = payload.preferences
await user.save()
return user
}
}
module.exports = UserController
Example 2: Type-safe service selection with enumerated values
Avoid dynamic class selection based on raw input. Use enumerated constants and strict mapping instead.
'use strict'
const processorMap = {
invoice: () => import('App/Processors/InvoiceProcessor'),
report: () => import('App/Processors/ReportProcessor')
}
class TaskController {
async run ({ request, auth }) {
const allowedTypes = new Set(['invoice', 'report'])
const { taskType, data } = request.only(['taskType', 'data'])
if (!allowedTypes.has(taskType)) {
return response.badRequest({ error: 'Invalid task type' })
}
const ProcessorClass = await processorMap[taskType]()
const processor = new ProcessorClass(auth.user)
return await processor.execute(data)
}
}
module.exports = TaskController
Example 3: Enforce strict typing in route binding
When using route parameters, cast and validate before use rather than relying on schema auto-casting.
'use strict'
class InvoiceController {
async show ({ params, request }) {
const id = Number(params.id)
if (!Number.isInteger(id) || id <= 0) {
return response.badRequest({ error: 'Invalid invoice ID' })
}
const invoice = await Invoice.findOrFail(id)
return invoice
}
}
module.exports = InvoiceController
These examples ensure that even with mTLS providing peer authentication, the application continues to enforce strict type expectations. middleBrick’s checks for Input Validation, Property Authorization, and Unsafe Consumption help identify where such guards are missing. Combining mTLS with precise validation reduces the attack surface for type confusion and related logic flaws.
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 |