HIGH type confusionadonisjsmutual tls

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 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 type confusion vulnerabilities in AdonisJS?
No. Mutual TLS secures transport and peer identity but does not validate application-level data types. Type confusion depends on input handling and validation, which must be enforced separately.
How can I test for type confusion in an mTLS-protected AdonisJS API?
Use middleBrick’s scanner to check Input Validation and Property Authorization findings. It cross-references your OpenAPI/Swagger spec (including $ref resolution) with runtime behavior to highlight missing type guards regardless of mTLS.