HIGH null pointer dereferenceadonisjsmutual tls

Null Pointer Dereference in Adonisjs with Mutual Tls

Null Pointer Dereference in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability

A null pointer dereference in AdonisJS when mutual TLS (mTLS) is enabled typically occurs when the application attempts to access properties or call methods on an object that is expected to be present (for example, the client certificate or the parsed TLS attributes) but is null because mTLS validation failed or was skipped. In AdonisJS, this can surface in request lifecycle hooks or within custom authentication guards that rely on TLS client data. If the TLS handshake succeeds but the application does not robustly handle missing certificate fields—such as subject alternative names or extended key usage—the code may dereference a null value when trying to extract identities, roles, or permissions.

With mTLS, the server requests and validates a client certificate. If the certificate is absent, malformed, or does not meet policy expectations, AdonisJS may still proceed into request handling code paths where developer assumptions guarantee the presence of certain attributes. For example, accessing request.tls.client.certificate.subject without checking for null can trigger a runtime exception. This is especially risky when the application integrates mTLS-based authorization logic that directly indexes into certificate metadata to derive access control decisions. The interplay between AdonisJS’s IoC container and route guards can obscure where the null originates, making the vulnerability harder to detect during code review.

An mTLS-enabled endpoint that parses certificate information into request context can inadvertently create a situation where middleware passes a partially initialized object down the pipeline. If a middleware layer assumes a non-null user context derived from TLS attributes and fails to validate that assumption, later handlers may encounter null where an object is expected. This pattern aligns with the broader class of null pointer dereferences, where missing checks on optional values lead to runtime crashes or inconsistent state. In security terms, an attacker who can cause the server to dereference a null pointer may trigger denial of service or force unexpected execution paths, depending on how the framework handles unhandled exceptions.

Real-world mappings include references to patterns common in API security testing, such as improper validation of client identity, which can overlap with BOLA/IDOR considerations when certificate-based identifiers are mishandled. Because AdonisJS applications often rely on structured request guards, failing to confirm the presence of TLS-derived data before use can expose sensitive logic to exploitation. The risk is not in the TLS protocol itself, but in the application’s assumptions about certificate contents, which must be validated as rigorously as any user-supplied input.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

To remediate null pointer dereference risks in AdonisJS with mTLS, enforce strict null checks on TLS-derived objects before use and design guards that handle missing or invalid certificates gracefully. Below are concrete code examples that demonstrate safe patterns for accessing client certificate data within AdonisJS request handling.

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { schema } from '@ioc:Adonis/Core/Validator'

export default class TlsAuthMiddleware {
  public async handle({ request, response, session }: HttpContextContract, next: () => Promise) {
    // Ensure the TLS client certificate is present and valid
    const clientCert = request.tls?.client?.certificate
    if (!clientCert) {
      return response.unauthorized({ error: 'Client certificate required' })
    }

    // Validate expected fields before dereferencing
    const subject = clientCert.subject
    if (!subject || !subject.commonName) {
      return response.badRequest({ error: 'Certificate subject is malformed' })
    }

    // Safely extract attributes with fallbacks
    const san = clientCert.extensions?.subjectAlternativeName?.dnsNames || []
    const hasRequiredDomain = san.includes('api.example.com')
    if (!hasRequiredDomain) {
      return response.forbidden({ error: 'Certificate does not include required domain' })
    }

    // Attach validated user context to request for downstream use
    request.authUser = { commonName: subject.commonName, domains: san }
    await next()
  }
}

In this example, the middleware checks for the existence of request.tls, the client certificate, and critical fields before accessing nested properties. By returning early with appropriate HTTP responses when validation fails, the code avoids null dereferences and ensures that only properly authenticated requests proceed.

// config/auth.ts — guard configuration that references the middleware
import { defineConfig } from '@ioc:Adonis/Core/Config'

export default defineConfig({
  guards: {
    web: {
      driver: 'jwt',
      tokenProvider: 'jwt',
      middleware: ['TlsAuth'],
    },
    api: {
      driver: 'jwt',
      tokenProvider: 'jwt',
      middleware: ['TlsAuth'],
    },
  },
})

For broader protection, combine the middleware with input validation schemas that explicitly require certificate fields. This approach ensures that assumptions about TLS data are verified at the boundary, reducing the chance of null pointer dereferences in downstream handlers and services. Using middleBrick’s scans can help verify whether your endpoints consistently enforce these checks across unauthenticated attack surfaces.

When integrating with the broader ecosystem, the CLI (middlebrick scan <url>) can be used in scripts to validate that your API endpoints expose proper mTLS handling, while the GitHub Action can enforce security gates in CI/CD. The MCP Server allows you to run these checks directly from AI coding assistants, supporting secure development workflows without requiring manual scans.

Frequently Asked Questions

What should I do if my AdonisJS app receives a request with a missing client certificate in mTLS mode?
Return an explicit unauthorized response and reject the request. Do not proceed to handlers that assume the presence of TLS-derived data, and log the event for audit purposes.
How can I test that my null checks for TLS attributes are effective?
Use targeted test cases that send requests with no certificate, malformed certificates, and certificates missing required extensions. Verify that the application responds with appropriate error codes and does not dereference null values.