HIGH bleichenbacher attackadonisjsapi keys

Bleichenbacher Attack in Adonisjs with Api Keys

Bleichenbacher Attack in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability

A Bleichenbacher attack is a cryptographic padding oracle attack that exploits error messages returned during decryption of RSA-encrypted data. In an API context, if an application decrypts an encrypted API key or token and reveals whether the padding is valid via timing differences or distinct error messages, an attacker can iteratively decrypt or forge valid tokens without knowing the key. This becomes relevant in AdonisJS when API keys are stored or transmitted encrypted and the application decrypts them on each request, returning different responses or status codes depending on padding validity.

Consider an AdonisJS route that receives an encrypted API key via an Authorization: Bearer <token> header, decrypts it using an RSA private key, and then checks the plaintext format. If the server responds with 401 Unauthorized for invalid padding and 403 Forbidden for valid padding but malformed content, an attacker can distinguish outcomes and mount a Bleichenbacher attack. AdonisJS itself does not introduce the vulnerability; it is introduced by how the application handles decryption and error differentiation. Common triggers include using Node.js crypto APIs directly without constant-time comparison and exposing stack traces or specific error messages to the client.

In a black-box scan, middleBrick tests unauthenticated endpoints that accept bearer tokens or encrypted identifiers. One of its 12 parallel checks is Input Validation, which includes attempts to submit malformed, oversized, or crafted tokens to observe server behavior. If the endpoint differentiates between padding errors and other validation failures, middleBrick flags the finding under Input Validation with severity High, noting potential oracle behavior. The LLM/AI Security checks are not directly relevant here unless the API endpoint exposes an LLM endpoint that also accepts encrypted input. middleBrick’s OpenAPI/Swagger analysis helps by identifying which endpoints expect authentication tokens and by cross-referencing spec definitions with runtime behavior to highlight inconsistencies that could facilitate an oracle attack.

Real-world examples involve endpoints that process encrypted JWTs or RSA-OAEP wrapped keys. If the AdonisJS app uses crypto.privateDecrypt and does not swallow exceptions or normalize error responses, timing differences or HTTP status code variances may be observable. Attackers can use this to perform Bleichenbacher-style decryption or signature forgery. Mitigations must ensure that all decryption paths return the same generic error and status code, and that decryption time does not depend on padding correctness.

Api Keys-Specific Remediation in Adonisjs — concrete code fixes

To prevent Bleichenbacher-style attacks, AdonisJS applications must ensure that decryption and validation of API keys do not leak information via timing or error messages. Below are concrete remediation steps with code examples.

1. Use constant-time comparison and unified error handling

After decrypting an API key, compare the result using a constant-time comparison and return a generic error response regardless of padding or validation failures.

import { Crypto } from '@adonisjs/core/build/standalone'
import timingSafeEqual from 'tsscmp'

export async function validateEncryptedApiKey(encryptedKey: string): Promise<boolean> {
  try {
    const decrypted = Crypto.privateDecrypt({
      key: process.env.RSA_PRIVATE_KEY!,
      padding: constants.constants.RSA_PKCS1_OAEP_PADDING,
    }, Buffer.from(encryptedKey, 'base64'))
    const apiKey = decrypted.toString('utf8')
    // Perform constant-time comparison against stored key or hash
    const isValid = timingSafeEqual(apiKey, process.env.STORED_API_KEY!)
    return isValid
  } catch (error) {
    // Always return false; do not expose error details
    return false
  }
}

Ensure the HTTP handler returns the same status code (e.g., 401) for both invalid key format and invalid padding, and avoid exposing stack traces in production.

2. Validate and normalize inputs before decryption

Check basic format constraints (e.g., base64 encoding, expected length) before attempting decryption to avoid invoking the RSA primitive on malformed input that could produce distinguishable errors.

import { schema } from '@ioc:Adonis/Core/Validator'

const apiKeySchema = schema.create({
  encrypted_key: schema.string({}, [
    (value, { reporter }) => {
      if (!/^[A-Za-z0-9+/=]+$/.test(value)) {
        reporter.report('field', 'encrypted_key', 'invalid_format')
      }
    },
  ]),
})

export const store = async (ctx: HttpContextContract) => {
  const payload = await validator.validate({ schema: apiKeySchema, data: ctx.request.body() })
  // Proceed with decryption only if format passes
}

3. Use symmetric keys for high-volume key validation when possible

If feasible, prefer symmetric encryption (e.g., AES-GCM) for API key validation to avoid RSA padding issues entirely. Store hashed versions of API keys and compare using constant-time functions.

import { Crypto } from '@adonisjs/core/build/standalone'
import timingSafeEqual from 'tsscmp'

export function verifyApiKey(candidate: string): boolean {
  const hashedCandidate = Crypto.hash('sha256', candidate)
  return timingSafeEqual(hashedCandidate, process.env.HASHED_API_KEY!)
}

4. Configure middleware to normalize responses

Use an HTTP middleware in AdonisJS to catch exceptions and standardize error responses so that no information about decryption internals is exposed.

import { ExceptionHandler } from '@adonisjs/core/build/legacy-exceptions'

export default class ExceptionHandler extends ExceptionHandler {
  public handle(error: any, ctx: HttpContextContract) {
    if (error.name === 'DecryptionError') {
      ctx.response.status(401).send({ error: 'Unauthorized' })
      return
    }
    super.handle(error, ctx)
  }
}

These measures ensure that API key validation does not act as a padding oracle. When combined with middleware that enforces uniform error handling, they reduce the risk of a successful Bleichenbacher attack.

Frequently Asked Questions

Can middleBrick detect a Bleichenbacher vulnerability during an API scan?
Yes. middleBrick tests input validation and error handling behavior. If an endpoint returns different status codes or error messages for malformed encrypted tokens versus other invalid inputs, the scan may flag a potential oracle issue under Input Validation with high severity.
Does the LLM/AI Security check in middleBrick apply to Bleichenbacher attacks in AdonisJS?
The LLM/AI Security checks focus on prompt injection, jailbreaks, and output leakage from LLM endpoints. They are not designed to detect cryptographic padding oracle behavior. Remediation for Bleichenbacher attacks should be implemented via secure decryption patterns and uniform error handling as shown.