HIGH beast attackhapiapi keys

Beast Attack in Hapi with Api Keys

Beast Attack in Hapi with Api Keys — how this specific combination creates or exposes the vulnerability

A Beast Attack (BOLA/IDOR) in Hapi when using API keys can occur when access controls are enforced at the authentication layer (e.g., validating an API key) but not consistently applied to each resource identifier in the request. In Hapi, this typically means an endpoint accepts a user identifier from the URL (e.g., /users/{id}) and trusts the API key to authorize access, without verifying that the authenticated subject owns or should access the provided {id}. Because API keys are often treated as a simple bearer token, a compromised or leaked key combined with predictable numeric IDs exposes a BOLA/IDOR vector: an attacker can iterate through IDs and read or modify other users’ data even though each request includes a valid key.

Under the unauthenticated scan profile, middleBrick tests this combination by probing endpoints that use API key authentication while manipulating resource identifiers. One of the 12 parallel checks, BOLA/IDOR, specifically looks for cases where a valid API key does not prevent access to other users’ resources. If your Hapi routes validate the key but do not enforce scope checks such as userId === key.associatedUserId, the scan will flag a finding. This exposes a gap where authentication (having a key) does not map to proper authorization (access only what the subject is permitted). The risk is especially relevant for endpoints that expose sensitive user data or allow state-changing operations when IDs are predictable and ownership is not rechecked server-side.

For example, consider a route that reads user profile data using a path parameter without correlating it to the key’s holder:

// Insecure: API key present, but {id} not verified against key scope
server.route({
  method: 'GET',
  path: '/users/{id}',
  options: {
    auth: 'api-key',
    handler: async (request, h) => {
      const userId = request.params.id;
      // Missing: ensure key is scoped to userId
      return userService.getProfile(userId);
    }
  }
});

An attacker with a valid API key can change {id} to access other profiles. middleBrick’s OpenAPI/Swagger analysis helps detect these issues by correlating path parameters with security schemes defined in the spec and cross-referencing runtime behavior. When combined with the framework’s route definitions, this enables detection of missing ownership checks that facilitate Beast Attacks. Addressing this requires tying the API key scope to the resource identifier and rechecking authorization on every request.

Api Keys-Specific Remediation in Hapi — concrete code fixes

Remediation centers on ensuring that a valid API key maps to the correct resource and that ownership is verified for every request. In Hapi, this means coupling the authentication validation with explicit authorization logic that checks the key’s associated subject against the requested identifier. Avoid relying on the key alone to enforce row-level security.

First, structure your API key validation to attach user-level metadata (such as user ID or allowed scopes) to the request object during authentication. Then, in each handler, compare the path or query identifier with this metadata before proceeding. Below is a secure Hapi pattern that demonstrates this approach:

// Secure: correlate API key scope with the requested user id
server.route({
  method: 'GET',
  path: '/users/{id}',
  options: {
    auth: 'api-key',
    handler: async (request, h) => {
      const userId = request.params.id;
      const keyScope = request.auth.credentials.scope; // e.g., { userId: '123' }
      if (keyScope.userId !== userId) {
        throw Boom.forbidden('Access denied: scope mismatch');
      }
      return userService.getProfile(userId);
    }
  }
});

Second, centralize authorization logic where feasible (e.g., in a pre-auth extension or a route helper) to avoid repeating checks across many routes. This ensures consistent enforcement and makes it easier to audit and test. For example, a helper can encapsulate the ownership check:

// Centralized authorization helper
function ensureUserAccess(request, h) {
  const userId = request.params.id;
  if (request.auth.credentials.userId !== userId) {
    throw Boom.forbidden('Access denied');
  }
  return true;
}

server.route({
  method: 'GET',
  path: '/users/{id}',
  options: {
    auth: 'api-key',
    pre: [{ method: ensureUserAccess, assign: 'accessCheck' }],
    handler: async (request, h) => {
      return userService.getProfile(request.params.id);
    }
  }
});

Additionally, prefer opaque identifiers or mapping tables instead of exposing sequential numeric IDs when feasible, reducing the feasibility of brute-force enumeration. Combine these practices with continuous scanning using tools like middleBrick’s CLI to validate that your routes remain protected after changes. The Pro plan’s continuous monitoring can alert you if a new route lacks proper scope checks, and the GitHub Action can fail builds when a security score drops below your chosen threshold, helping you catch regressions early.

Frequently Asked Questions

Can a Beast Attack happen even when API keys are rotated regularly?
Yes. Regular rotation reduces the impact of a leaked key, but if endpoints do not enforce ownership checks between the key and the resource identifier, an attacker who obtains a valid key can still perform a Beast Attack by iterating over IDs. Rotation must be paired with per-request authorization validation.
Does middleBrick’s OpenAPI/Swagger analysis help detect these issues in Hapi projects?
Yes. middleBrick’s OpenAPI/Swagger analysis resolves $ref chains and cross-references path parameters with declared security schemes. This can highlight routes where authentication is present but ownership or scope checks against identifiers are not evident in the spec or runtime behavior.