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