Dictionary Attack in Adonisjs with Mutual Tls
Dictionary Attack in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability
A dictionary attack targets authentication endpoints by systematically submitting common credentials. In AdonisJS, this typically maps to the login route that validates a username and password. When mutual Transport Layer Security (mTLS) is in use, the server requests a client certificate during the TLS handshake, but this does not inherently prevent credential-based brute force at the application layer. mTLS ensures the client possesses a valid certificate, yet once the TLS session is established, the login POST request with a username and password remains unprotected against exhaustive or high-velocity guesses.
The combination creates a nuanced risk: mMTLS provides strong identity assurance for clients, which may lead developers to assume the endpoint is fully secured. However, if rate limiting and account lockout are absent, an attacker who has obtained or guesses a valid client certificate (or uses a stolen certificate) can still perform a dictionary attack on the API path that mTLS protects. The scanner’s Authentication check can flag weak or missing rate controls even when mTLS is present, because the security check tests the unauthenticated attack surface and then probes the login mechanism.
Consider an AdonisJS route where certificate-based identity is read from the TLS connection but the username/password validation remains the sole gate for resource access. The system prompt leakage and active prompt injection tests in the LLM/AI Security category are not applicable here, but the Authentication and BOLA/IDOR checks remain relevant. A discovered finding might indicate that despite mTLS, the endpoint allows rapid attempts without throttling, enabling credential guessing. The presence of mTLS changes the threat model slightly: it prevents certain on-path impersonation attacks, but it does not stop an attacker who can present a valid certificate from hammering the login route with password guesses.
Real-world attack patterns include using compromised certificates paired with leaked credential lists. For compliance mappings, this scenario intersects with OWASP API Top 10:2023 Broken Authentication, and relevant standards such as PCI-DSS require strong access controls and monitoring for authentication abuse. middleBrick scans detect when authentication mechanisms lack sufficient rate constraints even when mTLS is configured, providing prioritized findings with severity and remediation guidance to tighten the login flow.
Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes
To secure an AdonisJS application with mutual TLS while mitigating dictionary attacks, enforce strict rate limiting and robust credential validation in addition to mTLS. Below are concrete code examples for an AdonisJS route that reads a client certificate and applies throttling to prevent rapid guessing.
First, configure the server to request and verify client certificates. In start/hooks.ts, adjust the HTTPS server setup to require client authentication:
import { defineConfig } from '@adonisjs/core/app'
import { HttpServer } from '@adonisjs/core/server'
export default defineConfig({
http: {
server: HttpServer,
async setupServer(server) {
server.tls = {
cert: '/path/to/server-cert.pem',
key: '/path/to/server-key.pem',
ca: '/path/to/ca-cert.pem',
requestCert: true,
rejectUnauthorized: true,
}
},
},
})
Next, in your login route, validate the certificate subject or serial to bind authentication state, and apply rate limiting using AdonisJS middleware. For example, create a rate limiter in start/rateLimiter.ts:
import { RateLimiter } from '@adonisjs/limiter'
export const limiter = new RateLimiter({
consumeRate: 5,
refillRate: 1,
refillInterval: 60,
capacity: 10,
})
Then, apply the limiter to the login route in routes.ts:
import Route from '@ioc:Adonis/Core/Route'
import { limiter } from './start/rateLimiter'
Route.post('/login', async ({ request, response, auth }) => {
const { username, password } = request.body()
// Optionally validate client certificate details from request
const clientCert = request.$ssl?.clientCert
if (!clientCert) {
return response.badRequest({ error: 'Client certificate required' })
}
// Enforce rate limit
await limiter.consume(request.ip())
// Perform credential verification
const user = await auth.use('api').attempt(username, password)
if (!user) {
return response.unauthorized({ error: 'Invalid credentials' })
}
return { ok: true }
})
This approach combines mTLS for client identity with application-level rate limiting to reduce the risk of dictionary attacks. The scanner’s checks can verify that rate limiting is present and that the endpoint does not allow unchecked attempts even when a valid certificate is presented. middleBrick’s findings will highlight whether authentication controls are insufficient, guiding you to implement such patterns.
Additionally, monitor for anomalous login patterns and consider progressive delays or CAPTCHA after repeated failures. Ensure that client certificates are managed securely and revoked upon compromise. These measures complement mTLS and align with frameworks like OWASP API Security Verification and compliance requirements such as PCI-DSS.