HIGH pii leakageadonisjsmutual tls

Pii Leakage in Adonisjs with Mutual Tls

Pii Leakage in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability

AdonisJS, a Node.js web framework, often handles sensitive payloads such as personally identifiable information (PII) in requests and responses. When mutual TLS (mTLS) is used, the assumption is that transport-layer authentication and encryption prevent unauthorized access. However, PII leakage can still occur due to framework behavior, middleware misconfiguration, or improper error handling, even when mTLS is enforced.

In an mTLS setup, both client and server present certificates. AdonisJS can be configured to require client certificates, but if the application logs request bodies, stack traces, or query details without redaction, PII may be exposed in logs or error outputs. For example, a route that accepts JSON containing email or phone numbers might inadvertently include these fields in console logs or unhandled rejection traces, which are accessible to users with limited access to logging systems.

Another scenario involves the serialization of responses. If AdonisJS controllers or serializers include sensitive fields (such as ssn or dob) in JSON output without filtering, and those responses are cached or monitored, PII can be exposed to unauthorized consumers. Middleware that attaches request context for debugging may also propagate PII across services if correlation IDs are stored with payload data.

Moreover, mTLS ensures identity, not data minimization. An authenticated client with valid certificates might still submit PII in parameters that are not intended for certain endpoints. Without explicit validation and schema-based sanitization, AdonisJS will process and potentially echo these fields in responses or logs, creating leakage pathways. This is especially relevant when integrating third-party services that require broad payload access but should only receive a subset of PII.

Real-world patterns include routes that bind request bodies directly to models or DTOs without stripping sensitive fields, or using global exception handlers that expose full request details in error messages. Even with mTLS, such practices can lead to PII leakage through verbose error pages or debug endpoints that are inadvertently exposed in development-like configurations.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

To mitigate PII leakage while using mutual TLS in AdonisJS, apply targeted remediation at the framework and application level. These fixes focus on input validation, response filtering, and safe error handling, while preserving mTLS benefits.

1. Enforce mTLS in AdonisJS server configuration

Configure the HTTPS server to request and validate client certificates. Use AdonisJS hook or provider to customize the TLS options. Below is a concrete example using the built-in HTTP server with TLS options in start/server.ts:

import { HttpServer } from '@adonisjs/core/http'
import { readFileSync } from 'fs'

export const http = new HttpServer({
  ssl: {
    key: readFileSync('path/to/server.key'),
    cert: readFileSync('path/to/server.crt'),
    ca: readFileSync('path/to/ca.crt'),
    requestCert: true,
    rejectUnauthorized: true,
  },
})

This setup ensures that only clients with valid certificates signed by the trusted CA can establish a connection. The requestCert and rejectUnauthorized flags enforce mutual authentication without altering application logic.

2. Sanitize and validate incoming PII before processing

Use schema validation to explicitly allow only necessary fields and strip or transform PII at the boundary. With AdonisJS v5+ using Lucid or custom validation, define a schema that excludes sensitive fields from being persisted or echoed:

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

const userSchema = schema.create({
  email: schema.string.optional(),
  phone: schema.string.optional(),
  // Exclude ssn, dob, or other PII unless explicitly required
})

export const userValidator = (ctx) => {
  const payload = ctx.request.validate({
    schema: userSchema,
  })
  // Proceed with sanitized payload
  return payload
}

For routes that must handle PII, apply additional masking in middleware before logging or forwarding data. This prevents raw PII from appearing in console logs or diagnostic snapshots.

3. Secure error handling and response serialization

Customize the exception handler to avoid exposing request details. In app/Exceptions/Handler.ts, filter stack traces and redact PII fields from error messages:

import { ExceptionHandler } from '@ioc:Adonis/Core/ExceptionHandler'

export default class CustomExceptionHandler extends ExceptionHandler {
  public handle(error, ctx) {
    // Redact PII from error messages
    const safeMessage = error.message?.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[REDACTED]') || 'An error occurred'
    
    if (error.name === 'ValidationException') {
      ctx.response.badRequest({ error: safeMessage, code: error.code })
      return
    }

    // Generic safe response
    ctx.response.status(error.status || 500).send({ error: safeMessage })
  }
}

This approach ensures that even if an error includes user input, sensitive PII fields such as emails are replaced before being logged or returned.

4. Control logging and debugging output

Avoid logging full request bodies in development or production. If logging is necessary, use a formatter that strips PII:

import { logger } from '@poppinss/dev-utils'

function safeLog(data: any) {
  const { email, phone, ssn, ...rest } = data
  logger.info('Request metadata', rest)
}

Integrate this pattern in route handlers or event listeners to prevent PII from persisting in log stores.

5. Enforce data minimization at integration boundaries

When mTLS routes involve third-party callbacks or webhooks, validate that only necessary data is shared. Use transformation layers to extract required non-PII fields and discard the rest before further processing.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does mutual TLS alone prevent PII leakage in AdonisJS applications?
No. Mutual TLS authenticates clients and servers but does not limit what data is processed, logged, or returned. PII can still be exposed through insecure logging, error messages, or insufficient input validation, even when mTLS is enforced.
How can I verify that my AdonisJS routes are not leaking PII despite using mTLS?
Review route handlers for direct logging of request bodies, audit exception handlers for verbose output, and validate that schemas exclude unnecessary PII fields. Use runtime scanning tools that inspect unauthenticated attack surfaces to detect exposed PII in responses and error paths.