HIGH phishing api keysadonisjsbasic auth

Phishing Api Keys in Adonisjs with Basic Auth

Phishing API Keys in AdonisJS with Basic Auth — how this specific combination creates or exposes the vulnerability

When an AdonisJS application uses HTTP Basic Authentication without additional protections, API keys or credentials can be exposed through phishing because the credentials are only base64-encoded, not encrypted. Basic Auth sends an Authorization header in the format Basic base64(username:password) on every request. If an attacker can trick a user or an upstream service into sending credentials to a malicious endpoint that mimics your AdonisJS API, the credentials are disclosed in clear text across the network.

In a typical AdonisJS setup, developers sometimes rely solely on Basic Auth for route or controller-level protection. For example:

// start/hooks.ts
import { defineHook } from '@adonisjs/core'
import { createAuthMiddleware } from '@adonisjs/auth'

export const auth = defineHook(() => {
  const auth = createAuthMiddleware({
    only: ['auth:basic'],
  })
  return { auth }
})

If the Basic Auth handler is misconfigured or if credentials are captured via a man-in-the-middle proxy or a phishing site that forwards requests to your real endpoint, an attacker can harvest the base64 string and decode it offline. Additionally, if AdonisJS logs incoming headers for debugging without redaction, API keys embedded in credentials may be written to logs, enabling further phishing or credential stuffing. The risk is amplified when Basic Auth is used over unencrypted channels or when developers inadvertently expose endpoints that accept credentials without additional context like HMAC-signed requests or rotating tokens.

Another phishing vector involves luring developers or operators to submit credentials to a fake dashboard or CI/CD integration that claims to "test" the AdonisJS API. Because middleBrick scans endpoints without authentication by default, an exposed Basic Auth-protected route might be tested against public scanners. If a submitted URL points to a phishing-collection endpoint rather than the true API, credentials can be harvested directly. This underscores the importance of validating endpoint authenticity before sharing URLs with any scanner or third-party service.

Basic Auth-Specific Remediation in AdonisJS — concrete code fixes

To mitigate phishing risks with Basic Auth in AdonisJS, move away from static credentials and implement dynamic, scoped tokens. Instead of embedding long-lived API keys in Basic Auth, generate short-lived tokens tied to specific scopes and enforce transport security.

1. Enforce HTTPS across all routes to prevent on-path interception. AdonisJS provides an app.js hook to reject non-TLS requests in production:

// start/hooks.ts
import { defineHook } from '@adonisjs/core'

export const hooks = defineHook(() => {
  return {
    onRequest: [() => import('@adonisjs/https')],
  }
})

2. Replace static Basic Auth credentials with a token-based approach using middleware that validates a custom header instead of the Authorization header. For example, use a custom X-API-Key header and validate it against a database or environment variable:

// start/hooks.ts
import { defineHook } from '@adonisjs/core'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export const auth = defineHook(() => {
  return {
    onRequest: [async (ctx: HttpContextContract) => {
      const apiKey = ctx.request.header('X-API-Key')
      const validKey = process.env.API_KEY_TOKEN
      if (!apiKey || apiKey !== validKey) {
        ctx.response.status(401).send({ error: 'Unauthorized' })
      }
    }],
  }
})

3. If you must retain Basic Auth, rotate credentials frequently and avoid using them for high-risk operations. Combine Basic Auth with an additional layer, such as a request signature or HMAC, to prevent replay attacks. For example:

// middleware/basic_auth_with_hmac.ts
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import crypto from 'crypto'

export async function validateHmac(ctx: HttpContextContract) {
  const authHeader = ctx.request.header('authorization')
  const timestamp = ctx.request.header('x-timestamp')
  const signature = ctx.request.header('x-signature')

  if (!authHeader || !timestamp || !signature) {
    ctx.response.status(400).send({ error: 'Missing headers' })
    return
  }

  const base64Creds = authHeader.replace('Basic ', '')
  const decoded = Buffer.from(base64Creds, 'base64').toString('utf-8')
  const [user, pass] = decoded.split(':')

  const expected = crypto
    .createHmac('sha256', pass)
    .update(timestamp)
    .digest('hex')

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    ctx.response.status(403).send({ error: 'Invalid signature' })
  }
}

4. Use AdonisJS environment-based configuration to ensure credentials are never hard-coded. Load secrets via .env and reference them securely:

// .env
API_BASIC_USER=api_user
API_BASIC_PASS=${API_BASIC_PASS_ENV}

By combining HTTPS, custom headers, short-lived tokens, and HMAC-based validation, the attack surface for phishing API keys in AdonisJS with Basic Auth is significantly reduced.

Frequently Asked Questions

Does middleBrick detect exposed API keys in Basic Auth headers during scans?
Yes. middleBrick scans unauthenticated endpoints and can detect API keys or credentials exposed in Basic Auth headers, including patterns that resemble secrets, keys, or tokens in responses or headers.
Can I submit any URL to middleBrick for scanning, including endpoints protected by Basic Auth?
You can submit any URL to middleBrick without credentials. Note that scans test the unauthenticated attack surface; if your endpoint requires authentication, findings may be limited to what is observable without valid credentials.