HIGH excessive data exposureadonisjsapi keys

Excessive Data Exposure in Adonisjs with Api Keys

Excessive Data Exposure in Adonisjs with Api Keys

Excessive Data Exposure occurs when an API returns more information than necessary for a given operation, and in AdonisJS applications that use API keys for authentication, this risk is often amplified by permissively configured key scopes and debug-friendly error handling. In AdonisJS, API keys are typically managed via an authentication provider such as AdonisJS/Auth or a custom provider, and they are commonly passed in the Authorization header as Bearer <key> or via a dedicated x-api-key header. When these keys are validated and used to fetch associated resources, the framework may inadvertently return entire database records—including fields such as internal IDs, hashed secrets, relational pointers, timestamps, and metadata—rather than a minimal, purpose-built response.

For example, an endpoint like GET /profile that is protected by an API key may query a User model and return the full row, including columns such as password_reset_token, two_factor_secret, or email_verification_status. If the API key is compromised or improperly scoped, an attacker can leverage this excessive data to perform further reconnaissance, such as identifying account relationships or inferring business logic. In AdonisJS, this often happens when controllers directly serialize models using model.serialize() or when JSON:API resources include all attributes by default without explicit denylisting or field filtering.

Another common scenario involves logging or error responses that expose API key usage patterns. If an AdonisJS application logs incoming requests—including headers containing API keys—and those logs are aggregated or exposed through debug endpoints, sensitive attribution data can leak. Additionally, misconfigured global exception handlers may return stack traces that reveal internal file paths, database query structures, or environment variables when an invalid or unrecognized API key is presented. These secondary exposures compound the primary risk of returning too much data, effectively turning a simple key validation endpoint into a source of intelligence for an attacker.

The LLM/AI Security checks in middleBrick specifically account for scenarios where API key–protected endpoints might leak system prompts or internal instructions through verbose error messages or overly detailed responses. While API keys themselves are not AI prompts, endpoints that expose structured debug data can be probed to test whether models can infer sensitive contexts from repeated, key-authenticated interactions. This is particularly relevant when API keys are tied to rate-limited or monitored resources, and responses include metadata that could hint at quota status or backend routing logic.

To assess this risk in AdonisJS, middleBrick scans endpoints that require API key authentication and evaluates the completeness of returned payloads. It checks whether response bodies contain unnecessary fields such as internal identifiers, cryptographic artifacts, or relational pointers that do not serve the immediate function of the endpoint. The scanner also looks for inconsistencies between documented schema expectations and actual runtime output, which often reveals hidden data exposure paths that are not apparent during development.

Because AdonisJS applications often power mobile or third-party integrations, excessive data exposure via API keys can persist across multiple consumer types. A single overexposed endpoint can become a pivot point for lateral exploration, especially when combined with weak key rotation policies or missing scope validation. By focusing on response minimization and strict field control, teams can significantly reduce the attack surface introduced by API key–based access in AdonisJS.

Api Keys-Specific Remediation in Adonisjs

Remediation focuses on ensuring that responses contain only the data required for the operation and that API key usage does not amplify exposure through logging, error handling, or serialization behavior. In AdonisJS, this is typically implemented within controllers and resource classes, where developers define exactly which fields are serialized.

Consider a controller that retrieves user data for an API key–authenticated request. Instead of returning the full model, define a dedicated resource that selects only necessary fields:

import { Resource } from '@ioc:Adonisjs/Lucid';

export default class UserProfileResource extends Resource {
  public toArray() {
    return {
      id: this.resource.id,
      username: this.resource.username,
      avatarUrl: this.resource.avatarUrl,
      subscriptionTier: this.resource.subscriptionTier,
    };
  }
}

Then in your controller:

import User from 'App/Models/User';
import UserProfileResource from 'App/Resources/UserProfile';

export default class ProfileController {
  public async show({ auth }) {
    const user = await User.findByOrFail('id', auth.user.id);
    return new UserProfileResource(user);
  }
}

This pattern prevents leakage of sensitive fields such as password, api_key, or two_factor_secret. It also makes the data contract explicit and easier to audit.

For endpoints that rely on API keys passed via headers, validate the key and scope early and avoid attaching the full authenticated model to the request context unless necessary. Instead, load only the metadata required for authorization:

import ApiKey from 'App/Models/ApiKey';

export default class ApiKeyMiddleware {
  public async handle(ctx, next) {
    const key = ctx.request.header('x-api-key');
    if (!key) {
      return ctx.response.unauthorized('Missing API key');
    }

    const apiKey = await ApiKey.query()
      .where('key', key)
      .preload('scopes')
      .limit(1)
      .first();

    if (!apiKey || !apiKey.isValid()) {
      return ctx.response.unauthorized('Invalid API key');
    }

    // Attach only key metadata, not the full model
    ctx.auth = { keyId: apiKey.id, scopes: apiKey.scopes.rows };
    await next();
  }
}

Additionally, ensure that error handlers do not expose API key–related details. Override the default exception handler to return generic messages for authentication failures:

import { HttpContextContract } from '@ioc:Adonisjs/Core/HttpContext';

export default class ExceptionHandler {
  public handle(error, ctx: HttpContextContract) {
    if (error.name === 'InvalidApiKeyError') {
      ctx.response.status(401).json({ error: 'Unauthorized' });
      return;
    }
    // fallback handling
    ctx.response.status(500).json({ error: 'Internal server error' });
  }
}

Finally, audit any logging mechanisms to ensure API keys are not written to logs or debug endpoints. Use structured logging that filters sensitive headers before output.

Related CWEs: propertyAuthorization

CWE IDNameSeverity
CWE-915Mass Assignment HIGH

Frequently Asked Questions

How does middleBrick detect excessive data exposure in AdonisJS APIs?
middleBrick compares the actual JSON response structure against the declared OpenAPI/Swagger schema (including $ref resolution) and flags fields present at runtime that are not documented or that fall outside a minimal field set for the endpoint.
Does middleBrick test API key endpoints for data exposure even when authentication is required?
middleBrick focuses on unauthenticated attack surface testing, so it evaluates endpoints that expose data without credentials. For authenticated endpoints, remediation must ensure responses are minimally scoped regardless of authentication method.