HIGH data exposureadonisjsapi keys

Data Exposure in Adonisjs with Api Keys

Data Exposure in Adonisjs with Api Keys

AdonisJS offers a flexible system for authenticating requests via API keys, typically managed through packages such as @adonisjs/auth or custom guards. When API keys are used without strict scoping, overly permissive routes, or proper validation, sensitive data can be exposed beyond the intended consumer. A common pattern is to register an API key guard and attach it to routes that return user profiles, billing information, or administrative views. If a route does not enforce scope restrictions or role-based checks, an attacker who obtains or guesses a key can read data that should be limited to specific tenants or permission sets.

Consider a route that lists user activity logs. Without explicit authorization checks tying the key to a specific user or organization, any key with access to that endpoint can view logs belonging to other users. The risk increases when API keys are passed in URLs or non-HTTPS environments, as they can be leaked in logs, browser history, or network traces. Even when keys are stored securely, developers might inadvertently include sensitive fields (such as email, password hashes, or internal IDs) in the serialized response because the controller does not filter the payload. AdonisJS does not automatically strip these fields, so the API can expose more data than the developer intends.

Another exposure vector involves endpoint discovery and metadata. If your AdonisJS application serves an OpenAPI spec at a route like /swagger.json without access controls, an attacker can enumerate all API keys–protected endpoints and infer the data landscape. Even when keys are validated, improper error handling can reveal whether a key exists or which fields are present in a record, aiding enumeration. For example, a 403 response might indicate authorization failure, while a 404 suggests the resource does not exist, allowing an attacker to map the data surface. Inconsistent rate limiting on key–authenticated routes can also enable low–speed scraping, where an attacker iterates over identifiers to harvest data piece by piece without tripping defenses.

Data exposure is not limited to the primary resource. Related resources loaded through relationships or included via query parameters can inadvertently disclose nested information. An endpoint that returns a user profile with an included subscription relationship might expose billing details if the API key has broader read permissions than intended. Because AdonisJS relies on developer-defined policies and guards, the framework does not automatically enforce least privilege. If policies are not aligned with key scopes, or if keys are shared across services, the blast radius of a leaked key expands. This is especially relevant when keys are long–lived or when rotation practices are inconsistent.

To illustrate a typical vulnerable setup, an AdonisJS project might define an API key guard in start/auth.ts and apply it to a route group. The controller then fetches records and returns them without filtering sensitive columns or enforcing record ownership. Because the scan tests unauthenticated attack surfaces, middleBrick can detect endpoints that accept API key identifiers as parameters but lack proper authorization, leading to data exposure findings. Remediation focuses on tightening scope, validating relationships, and ensuring responses contain only necessary data, which is covered in the next section.

Api Keys-Specific Remediation in Adonisjs

Remediation centers on precise scoping, strict validation, and minimal data exposure. Define a dedicated API key guard with limited permissions, and avoid reusing the same key across unrelated services. Use policy checks to ensure that a key can only access resources belonging to its owner or tenant. In AdonisJS, you can implement this by customizing the auth provider and adding explicit checks in routes or controllers.

Example of a scoped guard definition in start/auth.ts:

import { AuthConfig } from '@adonisjs/auth/types';

const authConfig: AuthConfig = {
  guard: 'api_key',
  providers: {
    apiKey: {
      driver: 'api_key',
      model: 'App/Models/User',
      keyField: 'api_key',
      scope: 'tenant',
    },
  },
};

export default authConfig;

In your controller, enforce record ownership and filter sensitive fields before serialization:

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import ActivityLog from 'App/Models/ActivityLog'

export default class ActivityLogsController {
  public async index({ request, auth }: HttpContextContract) {
    const keyUser = auth.getUserOrFail()
    const logs = await ActivityLog.query()
      .where('tenant_id', keyUser.tenantId)
      .preload('user', (userQuery) => {
        userQuery.select('id', 'username')
      })
      .select('id', 'action', 'created_at')
      .orderBy('created_at', 'desc')
      .limit(100)

    return logs

For endpoints that reference a specific resource by ID, validate that the key is allowed to access that record:

import Invoice from 'App/Models/Invoice'

public async show({ params, auth }: HttpContextContract) {
  const keyUser = auth.getUserOrFail()
  const invoice = await Invoice.query()
    .where('id', params.id)
    .where('tenant_id', keyUser.tenantId)
    .firstOrFail()

  return invoice.serialize({ fields: ['id', 'amount', 'status', 'due_date'] })
}

Rotate keys regularly and avoid embedding them in URLs. When returning JSON, explicitly select fields to prevent leakage of internal columns such as password_hash or remember_token. Combine these practices with route-level policies and consistent error handling to reduce the risk of data exposure. middleBrick can verify that endpoints with key–based access enforce these constraints and do not return excessive data, supporting a more secure API surface.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

How does middleBrick detect data exposure in AdonisJS API key endpoints?
middleBrick runs unauthenticated checks that look for endpoints accepting key-like identifiers without proper ownership or scope validation, and reviews response fields to identify sensitive data returned without filtering.
Can API keys in AdonisJS lead to indirect data exposure through metadata?
Yes. If an OpenAPI spec or error messages reveal the presence and structure of resources, an attacker can infer data shapes. Ensure metadata routes are restricted and error responses do not differentiate between missing resources and invalid keys.