HIGH race conditionadonisjsmutual tls

Race Condition in Adonisjs with Mutual Tls

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

A race condition in AdonisJS when Mutual TLS (mTLS) is in use typically arises at the intersection of asynchronous request handling and the stateful verification of client certificates. While AdonisJS does not inherently introduce the race condition, the framework’s patterns—such as lazy authentication hooks, shared in-memory caches, or unresolved promise chains—can expose timing windows when mTLS client identity is not firmly established before business logic executes.

Consider a scenario where an authentication hook validates the mTLS certificate and attaches a user identity to the request context, but the actual certificate revocation check (e.g., via OCSP or CRL) is performed asynchronously. An attacker could send rapid, concurrent requests that slip through the verification window between the initiation of the revocation check and its completion. Because mTLS binds identity to a client certificate, the server may have already associated the request with a valid-looking certificate while the revocation status is still being determined. This creates a TOCTOU (Time-of-Check-Time-of-Use) window specific to mTLS, where a certificate that should be rejected is briefly treated as valid.

Additionally, if session or token derivation based on mTLS attributes is deferred and handled in a non-atomic way, concurrent requests might derive the same session key or impersonate a user by exploiting ordering differences. For example, two simultaneous requests with the same mTLS certificate might both pass the initial cert validation but trigger duplicate or conflicting state updates in a shared store, leading to privilege escalation or unauthorized access if the application resolves these states inconsistently.

In AdonisJS, this often maps to the OWASP API Top 10 category ‘2023-A1: Broken Object Level Authorization’ (BOLA) and ‘2023-A7: Identification and Authentication Failures’, because the race condition undermines the assurance that the authenticated identity derived from mTLS is stable and exclusive per request. The framework’s support for OpenAPI/Swagger spec analysis helps map these risks to spec-defined security schemes, but runtime behavior must be monitored to ensure mTLS verification completes atomically before any authorization-sensitive logic runs.

Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on ensuring mTLS verification is completed synchronously and atomically before request processing, and that state derived from certificate attributes is handled in a concurrency-safe manner.

1. Enforce synchronous mTLS verification in the request lifecycle

Configure AdonisJS to require and validate client certificates before entering route handlers. Use the AdonisJS hook system to perform verification early and store only verified identity.

// start/hooks.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { verifyMtlsCertificate } from 'src/helpers/certs'

export const handle = async (ctx: HttpContextContract, next: () => Promise) => {
  const certInfo = verifyMtlsCertificate(ctx.request)
  if (!certInfo || !certInfo.verified) {
    ctx.response.unauthorized({ error: 'mTLS verification failed' })
    return
  }
  ctx.auth.user = { id: certInfo.subjectUserId, scope: certInfo.scopes }
  await next()
}

2. Use atomic checks for revocation and identity binding

Perform revocation and policy checks in a single, non-interleaved step. Avoid deferred or lazy checks that introduce timing gaps.

// helpers/certs.ts
import { checkRevocationStatus } from 'src/services/ocsp'

export function verifyMtlsCertificate(request: any): { verified: true, subjectUserId: string, scopes: string[] } | { verified: false } {
  const cert = request.client.verifiedCert // assume mTLS already negotiated at TLS layer
  if (!cert) return { verified: false }

  // Atomic revocation check before identity processing
  const revocation = checkRevocationStatus(cert)
  if (revocation !== 'valid') return { verified: false }

  // Parse identity from certificate fields
  return {
    verified: true,
    subjectUserId: parseUserId(cert.subject),
    scopes: parseScopes(cert.extensions),
  }
}

3. Configure AdonisJS server for mTLS

Ensure the underlying server (e.g., AdonisJS’s dev server or a reverse proxy in front) enforces mTLS by requesting and validating client certificates on every connection.

// server.ts or relevant server configuration
import { defineConfig } from '@adonisjs/core'

export default defineConfig({
  https: {
    key: '/path/to/server-key.pem',
    cert: '/path/to/server-cert.pem',
    ca: '/path/to/ca-bundle.pem',
    requestCert: true,  // ask client for cert
    rejectUnauthorized: true, // enforce valid, trusted client certs
  },
})

4. Avoid shared mutable state in concurrent flows

When deriving session or authorization state from mTLS attributes, use atomic writes or database-level constraints to prevent race conditions across concurrent requests from the same certificate.

// Example: upsert user session atomically
import { UserSession } from '@ioc:App/Models/UserSession'

export async function ensureSessionForUser(userId: string, scopes: string[]) {
  await UserSession.updateOrCreate(
    { user_id: userId },
    { scopes, lastSeen: new Date() }
  )
}

5. Map findings to compliance and monitoring

Use the middleBrick CLI to scan your AdonisJS API endpoints with mTLS configurations and review findings related to authentication and BOLA. The CLI outputs structured JSON that you can integrate into scripts or the Web Dashboard to track how mTLS-enabled endpoints perform against security checks.

# Scan an mTLS-protected AdonisJS endpoint
middlebrick scan https://api.example.com/openapi.json

Findings may highlight gaps such as missing revocation checks or non-atomic authorization, which can then be remediated using the patterns above.

Frequently Asked Questions

Does middleBrick test for race conditions in mTLS-enabled AdonisJS APIs?
middleBrick’s concurrency-focused checks can help identify timing-related risks around mTLS verification and authorization. Results appear in the report with severity, findings, and remediation guidance; refer to the dashboard or CLI for detailed breakdowns.
Can the middleBrick MCP Server be used to scan AdonisJS APIs during development?
Yes, the MCP Server lets you scan APIs directly from your AI coding assistant. It supports OpenAPI/Swagger spec analysis with full $ref resolution and runs 12 security checks in parallel, including Authentication and BOLA/IDOR, to provide prioritized findings without requiring credentials.