HIGH memory leakadonisjsmutual tls

Memory Leak in Adonisjs with Mutual Tls

Memory Leak in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability

A memory leak in AdonisJS when mutual TLS (mTLS) is enabled typically arises from the interaction between long-lived HTTPS server instances and how TLS sessions and request contexts are managed. mTLS requires both client and server to present certificates, which increases per-connection state. If AdonisJS or application code holds references to request or context objects beyond the request lifecycle—such as storing request-scoped data in global caches, attaching listeners to TLS sockets that are not cleaned up, or retaining streams in module-level arrays—these references can prevent garbage collection. Over time, repeated mTLS handshakes and persistent connections accumulate unreleased objects, leading to growing heap usage. This pattern is more pronounced under mTLS because each connection carries additional certificate metadata and session state compared to unencrypted or one-way TLS traffic.

Another contributing factor is improper handling of secure server options and streams within AdonisJS providers or custom server boots. For example, creating a new secure server instance per route or failing to reuse a properly configured HTTPS server can multiply TLS contexts and associated buffers. MiddleBrick scans can surface related findings such as Input Validation and Unsafe Consumption when malformed or unexpected certificates trigger abnormal code paths that exacerbate retention. While MiddleBrick does not fix or remediate, its findings include prioritized guidance to help developers address root causes like dangling references and unmanaged streams.

In practice, a leak may manifest as a steady increase in RSS and heap size under continuous mTLS traffic, with no immediate errors. Profiling tools can show many detached DOM-like structures or EventEmitter listeners that should have been released. Because mTLS adds cryptographic material and session tickets to each connection, the leak may accelerate compared to non-mTLS setups. Developers should correlate memory trends with the number of TLS handshakes and active secure connections, and use MiddleBrick’s unauthenticated scan to surface related configuration and validation issues that may contribute to retention.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

To mitigate memory leaks with mTLS in AdonisJS, focus on correct server creation, stream cleanup, and avoiding global retention of request-specific objects. Use a single reused HTTPS server instance with proper secure context options, and ensure all streams and listeners are released after each request.

Example: Proper mTLS server setup in AdonisJS

Configure the HTTPS server once in start/hooks.ts or a dedicated boot file, and reuse it across the application. This reduces the number of TLS contexts and avoids duplicated session state:

import { httpsServer } from '@adonisjs/core/types/server'
import fs from 'fs'

const tlsOptions = {
  key: fs.readFileSync('/etc/ssl/private/server.key'),
  cert: fs.readFileSync('/etc/ssl/certs/server.crt'),
  ca: fs.readFileSync('/etc/ssl/certs/ca-bundle.crt'),
  requestCert: true,
  rejectUnauthorized: true,
}

export const server: httpsServer = {
  async create() {
    const https = await import('https')
    const server = https.createServer(tlsOptions, (req, res) => {
      // Handled by AdonisJS pipeline; keep this minimal
    })
    return server
  },
}

Ensure that your server.ts references this shared server and does not create new instances per route or request:

import { defineServer } from '@adonisjs/core/server'
import { server as tlsServer } from './start/hooks'

export const server = defineServer({
  hostname: '0.0.0.0',
  port: 8443,
  tls: tlsServer,
})

Avoid retaining request-scoped data globally

Do not attach large objects or streams to global variables or module-level arrays. Instead, use request-scoped storage (e.g., request.getPrivateStore()) and clean up in hooks or middleware:

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

export const cleanupHook = {
  async afterResponse(ctx: HttpContextContract) {
    const store = ctx.getPrivateStore()
    // Explicitly release references
    store.dispose?.()
    // Remove any temporary listeners
    ctx.response.off('finish', someListener)
  },
}

Profile heap usage while generating many mTLS handshakes to confirm that objects are being reclaimed. MiddleBrick can highlight related Input Validation and Data Exposure findings that may indicate problematic certificate handling paths, but remediation actions such as refactoring server lifecycle and scoping must be implemented by the development team.

Frequently Asked Questions

Can MiddleBrick detect a memory leak in AdonisJS with mTLS?
MiddleBrick scans an API endpoint without authentication and reports security findings and risk scores. It does not directly detect runtime memory leaks, but it can surface related issues such as Input Validation, Data Exposure, and Unsafe Consumption that may contribute to retention. Use runtime profiling tools alongside MiddleBrick findings to investigate memory growth.
What should I do if MiddleBrick flags risky certificate handling in my AdonisJS app?
Follow the remediation guidance in the findings, such as validating certificate inputs, avoiding global retention of request state, and reusing a single mTLS server configuration with proper secure options. Implement cleanup hooks and ensure streams and listeners are released per request, then re-scan with MiddleBrick to observe changes in related security checks.