HIGH dictionary attackadonisjsbasic auth

Dictionary Attack in Adonisjs with Basic Auth

Dictionary Attack in Adonisjs with Basic Auth — how this specific combination creates or exposes the vulnerability

A dictionary attack against an AdonisJS application using HTTP Basic Auth leverages two characteristics of Basic Auth: credentials are transmitted on every request (base64-encoded, not encrypted) and authentication is typically implemented as a single endpoint or filter that validates the credentials on each request. When these characteristics are combined with weak account policies, the attack surface is clear.

In AdonisJS, Basic Auth is commonly enforced via an authentication middleware or an auth.ts configuration that validates the Authorization header. If the application does not enforce strict rate limiting on the authentication route or on all routes protected by Basic Auth, an attacker can submit many username and password combinations per minute. The attacker iterates over a list of common usernames (e.g., admin, root, api) and passwords sourced from a dictionary, sending repeated requests until a valid credential pair is found.

Because Basic Auth does not inherently include account lockout or progressive delays, each request is evaluated independently. If the AdonisJS route handling authentication does not return consistent timing responses and does not use additional protections, timing differences may leak information about whether a username exists. The scanner’s Authentication check flags missing rate limiting, while the BOLA/IDOR and BFLA checks can detect whether privilege escalation is possible once access is gained via a dictionary-derived credential.

Additional checks such as Input Validation, Data Exposure, and Encryption are relevant because Basic Auth transmits credentials in every request. Without TLS (detected by the Encryption check), credentials are exposed in transit; even with TLS, the lack of additional safeguards means intercepted credentials can be reused. The scanner’s LLM/AI Security checks are not directly relevant to Basic Auth dictionary attacks but help ensure no prompt or configuration leakage compounds the risk.

To contextualize the risk, consider a scenario where an API endpoint is exposed without rate limiting. An attacker runs a script that iterates through thousands of password guesses. The scanner’s findings would highlight weak rate limiting, missing account lockout, and possibly excessive permissions if a low-privilege account is compromised and then exploited via BOLA to access other resources.

Basic Auth-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on preventing rapid credential guessing and ensuring credentials are handled securely. Implement rate limiting on authentication attempts, enforce strong passwords, and avoid hardcoding credentials in source code or environment files that could be exposed.

Example of enforcing Basic Auth in AdonisJS with route-level middleware and proper error handling:

// start/hooks.ts
import { Exception } from '@poppinss/utils'

export const auth = async (ctx, next) => {
  const authHeader = ctx.request.header('authorization')
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    ctx.response.status(401).send({ error: 'Unauthorized' })
    return
  }
  const base64 = authHeader.split(' ')[1]
  const decoded = Buffer.from(base64, 'base64').toString('utf-8')
  const [username, password] = decoded.split(':')

  // Validate credentials against your user store
  const user = await User.findBy('username', username)
  if (!user || user.password !== hashPassword(password)) {
    ctx.response.status(401).send({ error: 'Invalid credentials' })
    return
  }

  // Attach user to context for downstream handlers
  ctx.auth = { user }
  await next()
}

// routes.ts
Route.get('/secure', auth, async (ctx) => {
  ctx.response.send({ message: 'Access granted', user: ctx.auth.user })
})

Example of applying rate limiting using AdonisJS middleware to protect authentication endpoints:

// start/hooks.ts
import { RateLimiterMemory } from 'rate-limiter-flexible'

const rateLimiter = new RateLimiterMemory({
  points: 5, // 5 attempts
  duration: 60, // per 60 seconds
})

export const rateLimitAuth = async (ctx, next) => {
  const ip = ctx.request.ip()
  try {
    await rateLimiter.consume(ip)
    await next()
  } catch (rateLimiterRes) {
    ctx.response.status(429).send({ error: 'Too many attempts, try later' })
  }
}

// Combine rate limiting with auth hook
Route.post('/login', rateLimitAuth, async (ctx) => {
  // handle login if using form-based credentials; for Basic Auth, validation occurs in auth hook
})

Additional remediation guidance includes enforcing HTTPS via middleware to protect credentials in transit, rotating credentials regularly, and using strong password policies. The dashboard can track your security scores over time, the CLI can integrate scanning into scripts, and the GitHub Action can fail builds if risk scores drop below your configured threshold.

Frequently Asked Questions

Does middleBrick fix dictionary attack findings in Adonisjs?
No. middleBrick detects and reports findings with remediation guidance. It does not fix, patch, block, or remediate vulnerabilities.
How can I validate that rate limiting is effective against dictionary attacks?
Use the middleBrick CLI to rescan after implementing rate limiting and review the Authentication and Rate Limiting findings. The report includes severity, specific checks, and actionable remediation guidance.