HIGH missing tlsadonisjsmutual tls

Missing Tls in Adonisjs with Mutual Tls

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

When an AdonisJS service configured for mutual TLS (mTLS) runs without a valid listener-side TLS stack, it exposes an unauthenticated attack surface that directly undermines the intended client authentication guarantees. mTLS requires both the server and the client to present and validate certificates; if the server does not enforce TLS at all, clients may fall back to plaintext HTTP or connect to an unintended endpoint, bypassing certificate verification entirely. This combination creates a critical channel where authentication mechanisms are assumed active but are actually absent, allowing unauthenticated network interaction that mTLS was designed to prevent.

In practice, this misconfiguration often surfaces during development or when migrating services to HTTPS. An AdonisJS app might have mTLS policies defined in its proxy or ingress (e.g., requiring client certificates), while the application itself listens on HTTP without enforcing TLS. An attacker can route traffic to the HTTP listener, avoiding client certificate checks, and exploit endpoints that should be restricted to mTLS-authenticated clients. This can lead to unauthorized access to sensitive routes, data exposure, and privilege escalation paths that align with BOLA/IDOR and authentication-related checks in middleBrick’s scan. middleBrick’s Authentication and Authentication checks would flag this as a high-severity finding because the expected mTLS handshake is never enforced on the server side.

Furthermore, without TLS, metadata such as client certificate claims never make it into the request context, breaking assumptions in route-level guards and middleware. middleBrick’s Property Authorization and Input Validation checks may detect missing contextual constraints, but the root cause is the missing transport-layer enforcement. When mTLS is advertised but not implemented, compliance mappings to OWASP API Top 10 (2023) A07:2021 — Identification and Authentication Failures and A02:2021 — Cryptographic Failures become evident, as the system fails to provide authenticated and confidential transport as required. middleBrick’s OWASP and compliance mapping helps highlight these gaps by correlating findings with recognized frameworks.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

To remediate missing TLS in an AdonisJS application intended to use mutual TLS, enforce TLS at the server level and validate client certificates before processing requests. Below are concrete, syntactically correct examples that you can apply in your AdonisJS project.

1. Configure HTTPS server with client certificate verification

Use the built-in HTTPS module in your start/server.ts to create an HTTPS server that requests and validates client certificates. Ensure the server only accepts connections when a valid certificate is presented and mapped to an authenticated context.

import { Ignitor } from '@adonisjs/core/ignitor';
import fs from 'fs';
import https from 'https';

const options = {
  key: fs.readFileSync('/path/to/server.key'),
  cert: fs.readFileSync('/path/to/server.crt'),
  ca: fs.readFileSync('/path/to/ca.crt'),
  requestCert: true,
  rejectUnauthorized: true,
};

https.createServer(options, (req, res) => {
  // After rejectUnauthorized, req.client.verifiedCert is available in Node.js
  const cert = req.client?.verifiedCert;
  if (!cert) {
    res.writeHead(401);
    res.end('mTLS required');
    return;
  }
  // Optionally extract subject or SAN for user mapping
  const subject = cert.subject;
  (req as any).remoteUser = subject; // example mapping
  new Ignicator().fireHttpServer();
}).listen(443, () => {
  console.log('mTLS-enabled HTTPS server running on port 443');
});

2. Enforce TLS in AdonisJS provider boot (start.ts)

Add a boot method in start.ts to validate that the connection is secured before the application boots certain providers, ensuring runtime enforcement aligns with configuration.

import { Application } from '@adonisjs/core/types';

export default class AppBootstrapper {
  constructor(protected app: Application) {}

  async ready() {
    const tlsEnabled = this.app.config.get('tls.enabled', false);
    const isHttps = this.app.request.secure;

    if (tlsEnabled && !isHttps) {
      console.error('FATAL: Application requires TLS but is running over HTTP');
      process.exit(1);
    }
  }
}

3. Middleware to verify client certificate claims

Implement a lightweight middleware that checks the presence and validity of client certificate fields, rejecting requests that do not meet policy requirements. This complements the transport-layer enforcement with application-level checks.

import { HttpContextContract } from '@adonisjs/core/http';

export default class MtlsAuthMiddleware {
  public async handle(ctx: HttpContextContract, next: () => Promise) {
    const request = ctx.request;
    // In Node.js with TLS, verified cert is attached by the server
    const cert = (request as any).remoteUser || (request as any).client?.verifiedCert;
    if (!cert) {
      return ctx.response.unauthorized('Client certificate required');
    }
    // Example: enforce specific OU or SAN
    const allowedOu = 'api-clients';
    if (!cert.ou?.includes(allowedOu)) {
      return ctx.response.forbidden('Insufficient certificate privileges');
    }
    await next();
  }
}

4. Environment-driven TLS configuration

Keep sensitive paths configurable and avoid hardcoding certificate locations. Use environment variables and AdonisJS schema validation to ensure safe defaults and prevent runtime misconfiguration.

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

const tlsConfigSchema = schema.create({
  enabled: schema.boolean(),
  keyPath: schema.string.optional(),
  certPath: schema.string.optional(),
  caPath: schema.string.optional(),
});

export default tlsConfigSchema.validate(
  Object.fromEntries(Object.entries(env.toJSON()).filter(([key]) => key.startsWith('TLS_')))
);

By combining these practices, you ensure that AdonisJS enforces mTLS consistently, eliminating the gap where TLS is assumed but missing. This reduces the risk of unauthenticated access and aligns with the security checks performed by middleBrick’s Authentication, Property Authorization, and Compliance modules.

Related CWEs: encryption

CWE IDNameSeverity
CWE-319Cleartext Transmission of Sensitive Information HIGH
CWE-295Improper Certificate Validation HIGH
CWE-326Inadequate Encryption Strength HIGH
CWE-327Use of a Broken or Risky Cryptographic Algorithm HIGH
CWE-328Use of Weak Hash HIGH
CWE-330Use of Insufficiently Random Values HIGH
CWE-338Use of Cryptographically Weak PRNG MEDIUM
CWE-693Protection Mechanism Failure MEDIUM
CWE-757Selection of Less-Secure Algorithm During Negotiation HIGH
CWE-261Weak Encoding for Password HIGH

Frequently Asked Questions

How does missing TLS interact with mTLS configurations in AdonisJS?
If the server does not enforce TLS while mTLS policies are expected, clients can bypass certificate validation over plaintext HTTP, nullifying mTLS guarantees and exposing authentication and authorization boundaries.
What checks does middleBrick perform that would flag missing TLS with mTLS?
middleBrick’s Authentication check flags missing transport-layer enforcement, while Property Authorization and Compliance checks map the gap to frameworks such as OWASP API Top 10 A07:2021 and A02:2021.