HIGH missing authenticationadonisjsmutual tls

Missing Authentication in Adonisjs with Mutual Tls

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

Mutual Transport Layer Security (mTLS) requires both the client and the server to present valid certificates during the TLS handshake. In Adonisjs, mTLS is typically enforced at the infrastructure or proxy layer (e.g., Nginx, Envoy, or a load balancer) and not directly in application code. When authentication is missing or misconfigured in this setup, the API can be exposed even though mTLS appears to be in place.

Consider a deployment where Adonisjs runs behind a reverse proxy that handles mTLS verification. If the proxy is configured to forward requests without validating the client certificate or if the Adonisjs route definitions do not require authentication, an unauthenticated request can reach the application layer. This often occurs when developers assume mTLS alone is sufficient for authorization, but mTLS only establishes identity, not permissions. Without explicit route-level or policy-based checks in Adonisjs, any client that presents a valid certificate (or bypasses certificate validation) can access protected endpoints.

For example, an Adonisjs route defined as Route.get('/users/:id', 'UsersController.show') with no authentication guard can be invoked by any mTLS-enabled client. If the proxy does not enforce strict client certificate verification or if the certificate validation is downgraded to 'optional,' an attacker could connect with a self-signed or revoked certificate that the proxy accepts. The request then reaches Adonisjs as authenticated, but the application has no additional check to confirm scope, role, or consent. This gap between transport-layer identity and application-layer authorization is a common cause of Missing Authentication in mTLS environments.

In a black-box scan, middleBrick tests for Missing Authentication by probing endpoints that should require credentials while operating without them. It checks whether sensitive operations or data are exposed when no valid authentication context is provided, even when mTLS is negotiated. Findings include missing route guards, overly permissive proxy configurations, and lack of scope validation in Adonisjs controllers, all of which can lead to unauthorized data access or operations.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

To secure Adonisjs applications in an mTLS environment, combine robust proxy configuration with explicit route and policy enforcement. Below are concrete steps and code examples.

1. Enforce client certificate validation at the proxy

Ensure your reverse proxy (e.g., Nginx) is configured to require and verify client certificates. Example Nginx snippet:

server {
  listen 443 ssl;
  ssl_certificate /etc/ssl/certs/server.crt;
  ssl_certificate_key /etc/ssl/private/server.key;

  ssl_verify_client on;
  ssl_client_certificate /etc/ssl/certs/ca.crt;

  location / {
    proxy_pass http://localhost:3333;
    proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
    proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
  }
}

This configuration rejects requests without a valid client certificate signed by the trusted CA. The headers X-SSL-Client-Verify and X-SSL-Client-DN can be used in Adonisjs for logging or supplemental checks, but should not replace route guards.

2. Add route-level authentication guards in Adonisjs

Use Adonisjs auth providers to enforce authentication on sensitive routes. For example, with the default session provider:

// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'

Route.group(() => {
  Route.get('/users/me', 'UsersController.me').middleware(['auth'])
  Route.resource('users', 'UsersController').apiOnly().middleware({ only: ['index', 'show'], middlewares: ['auth'] })
}).prefix('api/v1')

For token-based scenarios (e.g., JWT), use the jwt middleware:

// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'
import jwtMiddleware from 'ioc:middleware/jwt'

Route.get('/admin', 'AdminController.index').middleware([jwtMiddleware])

Ensure your middleware pipeline validates the presence and correctness of credentials on every request, regardless of mTLS status.

3. Validate scopes and roles within controllers

Even with mTLS and route guards, validate that the authenticated principal has the right scope or role. Example in a controller:

// app/Controllers/Http/UsersController.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class UsersController {
  public async show({ params, auth }: HttpContextContract) {
    const user = await auth.authenticate()
    if (!user.canView(params.id)) {
      throw new ResponseStatusException('forbidden', 'You cannot view this resource')
    }
    return User.findOrFail(params.id)
  }
}

This ensures that identity established by mTLS is further constrained by application-level permissions.

4. Reject requests with missing or invalid client certs at the app layer (defense in depth)

In Adonisjs, you can add a global middleware to verify that the request includes a valid client identity when required:

// app/Middleware/RequireMtls.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class RequireMtls {
  public async handle(ctx: HttpContextContract, next: () => Promise) {
    const clientCert = ctx.request.header('x-ssl-client-verify')
    if (process.env.NODE_ENV === 'production' && clientCert !== 'SUCCESS') {
      ctx.response.status = 400
      response.body = { error: 'mTLS client certificate required' }
      return
    }
    await next()
  }
}

Register this middleware selectively for routes that demand strict mTLS validation.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

Does mTLS alone satisfy authentication requirements in Adonisjs?
No. mTLS provides transport-layer identity but does not enforce application-level permissions. Adonisjs routes must still use explicit authentication guards and role/scope checks to prevent Missing Authentication.
Can middleBrick detect Missing Authentication in mTLS-protected APIs?
Yes. middleBrick tests endpoints without relying on client certificates and checks whether authentication is required at the application layer. It identifies Missing Authentication findings when endpoints expose sensitive functionality without proper guards, even if mTLS is negotiated at the proxy.