HIGH broken authenticationadonisjsbasic auth

Broken Authentication in Adonisjs with Basic Auth

Broken Authentication in Adonisjs with Basic Auth — how this specific combination creates or exposes the vulnerability

AdonisJS is a Node.js web framework that does not provide built-in protection against common authentication weaknesses when you implement HTTP Basic Authentication yourself. Using Basic Auth without additional controls can create or expose broken authentication because the mechanism relies on sending credentials in an easily decoded format on every request. If TLS is not enforced consistently, credentials are exposed in transit. If the implementation does not enforce strong credential storage, attackers can obtain or brute-force weak hashes. If rate limiting or account lockout is missing, online password guessing becomes feasible.

Basic Auth sends an RFC 7617–formatted header (Authorization: Basic base64(username:password)). Base64 is not encryption; it is trivial to decode. Therefore, any interceptor who sees the header can recover the credentials unless TLS protects the entire session. In AdonisJS, a route that reads the header without enforcing HTTPS and without additional checks exposes an unauthenticated attack surface that middleBrick’s unauthenticated scan can detect as a potential authentication bypass or credential exposure finding under Authentication and Data Exposure checks.

Within the context of the OWASP API Top 10, broken authentication often maps to broken access control and insufficient encryption. AdonisJS applications that use Basic Auth for API endpoints must ensure that credentials are verified securely on each request, that sessions or tokens are not reused insecurely, and that rate limiting is applied to mitigate brute-force attacks. Without these controls, an attacker who intercepts or guesses a valid username and password can impersonate a user indefinitely, which an API security scan can surface as a high-severity finding.

Additionally, if the application reuses the same credentials across environments or fails to rotate secrets, the risk increases. MiddleBrick’s 12 security checks, including Authentication and Data Exposure, are designed to surface these issues in an unauthenticated scan by analyzing the OpenAPI specification and runtime behavior. The scanner does not fix the problem but provides prioritized findings with remediation guidance to help developers strengthen authentication in AdonisJS when Basic Auth is required.

Basic Auth-Specific Remediation in Adonisjs — concrete code fixes

To reduce the risk of broken authentication when using Basic Auth in AdonisJS, enforce HTTPS, store credentials safely, and add rate limiting. Below are concrete, working examples you can apply directly in your routes and providers.

1. Enforce HTTPS in production

Ensure all requests use TLS. In AdonisJS, you can enforce HTTPS at the route level or via middleware. The following route condition checks for secure connections before validating credentials:

import Route from '@ioc:Adonis/Core/Route'

Route.get('/secure-endpoint', async ({ request, response }) => {
  if (!request.secure()) {
    return response.status(403).send({ error: 'HTTPS required' })
  }
  // Proceed with Basic Auth validation
})

2. Secure credential verification with Base64 decoding

Parse and verify credentials on each request without storing passwords in plaintext. Use a constant-time comparison where possible and avoid leaking timing information. This example decodes the header and checks credentials against environment variables:

import Route from '@ioc:Adonis/Core/Route'
import { base64 } from '@ioc:Adonis/Core/Helpers'

Route.get('/api/data', async ({ request, response }) => {
  const authHeader = request.headers().authorization
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return response.status(401).header('WWW-Authenticate', 'Basic').send({ error: 'Unauthorized' })
  }

  const base64Token = authHeader.split(' ')[1]
  const token = Buffer.from(base64Token, 'base64').toString('utf-8')
  const [username, password] = token.split(':')

  const validUser = process.env.BASIC_AUTH_USER
  const validPass = process.env.BASIC_AUTH_PASS

  if (username !== validUser || password !== validPass) {
    return response.status(401).header('WWW-Authenticate', 'Basic').send({ error: 'Invalid credentials' })
  }

  return response.send({ data: 'Protected resource' })
})

3. Add rate limiting to mitigate brute-force attacks

Basic Auth is vulnerable to online guessing if attackers can attempt many passwords. Implement rate limiting per IP or per credential to increase attacker cost. AdonisJS allows easy integration with third-party rate limiters; conceptually, limit login attempts per source:

import Route from '@ioc:Adonis/Core/Route'
import RateLimiter from 'some-rate-limiter'

const limiter = new RateLimiter({ windowMs: 60 * 1000, max: 10 }) // 10 requests per minute

Route.post('/login', async ({ request, response }) => {
  const ip = request.ip()
  if (!await limiter.check(ip)) {
    return response.status(429).send({ error: 'Too many attempts' })
  }

  const authHeader = request.headers().authorization
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return response.status(401).header('WWW-Authenticate', 'Basic').send({ error: 'Unauthorized' })
  }

  const base64Token = Buffer.from(authHeader.split(' ')[1], 'base64').toString('utf-8')
  const [username, password] = base64Token.split(':')

  if (username !== process.env.BASIC_AUTH_USER || password !== process.env.BASIC_AUTH_PASS) {
    limiter.fail(ip)
    return response.status(401).header('WWW-Authenticate', 'Basic').send({ error: 'Invalid credentials' })
  }

  limiter.succeed(ip)
  return response.send({ data: 'Authenticated' })
})

4. Use middleware for reusable Basic Auth checks

To avoid repeating logic, create an auth middleware that validates credentials and enforces HTTPS. This keeps route handlers clean and ensures consistent protection across endpoints that require Basic Auth.

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { middleware } from '@ioc:Adonis/Core/Middleware'

const basicAuth = middleware(async (ctx, next) => {
  if (!ctx.request.secure()) {
    return ctx.response.status(403).send({ error: 'HTTPS required' })
  }

  const authHeader = ctx.request.headers().authorization
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    ctx.response.header('WWW-Authenticate', 'Basic')
    return ctx.response.status(401).send({ error: 'Unauthorized' })
  }

  const token = Buffer.from(authHeader.split(' ')[1], 'base64').toString('utf-8')
  const [username, password] = token.split(':')

  if (username !== process.env.BASIC_AUTH_USER || password !== process.env.BASIC_AUTH_PASS) {
    return ctx.response.status(401).header('WWW-Authenticate', 'Basic').send({ error: 'Invalid credentials' })
  }

  await next()
})

export default basicAuth

Apply the middleware to routes that require protection. This pattern centralizes security checks and makes it easier to audit and update authentication behavior.

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 middleBrick detect missing HTTPS enforcement when Basic Auth is used in AdonisJS?
Yes. middleBrick’s Authentication and Data Exposure checks can identify missing HTTPS enforcement and credential exposure risks when Basic Auth is used, providing prioritized findings and remediation guidance.
Can middleBrick test authenticated endpoints when using Basic Auth in AdonisJS?
middleBrick scans the unauthenticated attack surface by default. To include authenticated areas, supply credentials via environment variables or configuration as supported by the scan setup; this extends coverage to authenticated paths while following the tool’s documented capabilities.