HIGH bola idorrestifyapi keys

Bola Idor in Restify with Api Keys

Bola Idor in Restify with Api Keys — how this specific combination creates or exposes the vulnerability

Broken Object Level Authorization (BOLA) occurs when an API exposes one object identifier (such as a resource ID) and allows a subject to perform actions on objects they do not own. In Restify, using API keys for authorization can inadvertently create or expose BOLA when the key identifies the client but does not enforce ownership checks on the resource itself. For example, an API key may scope access to a tenant or a user group, yet endpoints like GET /accounts/:account_id continue to trust the caller-supplied :account_id without verifying that the authenticated API key is allowed to access that specific account.

Consider a typical Restify handler that uses an API key for authentication but then directly uses the request parameter to query a database:

server.get('/accounts/:id', (req, res, next) => {
  const accountId = req.params.id;
  const account = db.getAccount(accountId);
  res.send(account);
  return next();
});

If authentication is implemented via an API key middleware that sets req.apiKey but the handler does not compare req.apiKey.allowedAccounts or similar with accountId, an attacker can iterate numeric or predictable IDs and read accounts belonging to other clients. This is a classic BOLA: the API key proves identity and perhaps scope, but does not enforce object-level permissions.

In some configurations, API keys may embed metadata such as tenant_id or user_id. Even then, BOLA arises if the application trusts the client-supplied identifier instead of deriving the allowed object set from the key metadata. For instance, a key might carry { tenant: 'acme' }, yet the endpoint uses a userId path parameter without confirming that userId belongs to the tenant encoded in the key. The risk is exacerbated when IDs are sequential, unguessable values are not enforced, or when the API key is long-lived and leaked, enabling horizontal privilege escalation across objects.

To detect this, middleBrick performs unauthenticated scans that submit valid API keys (if provided) and then attempt to access other objects by manipulating identifiers. It compares authorization context from the key (when extractable from the payload or introspection) with runtime responses to determine whether access control is enforced at the object level. Findings highlight endpoints where object identifiers are accepted without ownership or tenant checks, even when an API key is present.

Api Keys-Specific Remediation in Restify — concrete code fixes

Remediation centers on ensuring that every access to a resource validates both the API key and the object ownership or tenant mapping. Do not rely on the key alone to gate access to a specific object identifier. Instead, enforce server-side checks that tie the key’s metadata to the requested resource.

One approach is to store allowed mappings server-side (e.g., in a cache or database) and resolve them at runtime. For example, when issuing API keys, record which accounts the key can access. In the handler, look up these mappings rather than trusting the client-supplied ID:

server.get('/accounts/:id', (req, res, next) => {
  const accountId = req.params.id;
  const apiKey = req.apiKey; // set by auth middleware
  if (!apiKey) { return res.send(401); }

  // server-side mapping: which accounts this key can access
  const allowed = allowedAccountsForApiKey(apiKey.id);
  if (!allowed.includes(accountId)) {
    return res.send(403);
  }

  const account = db.getAccount(accountId);
  res.send(account);
  return next();
});

Alternatively, encode tenant or user identifiers into the key itself (e.g., as a scoped JWT or opaque key with embedded claims) and validate those claims on each request. The handler then derives the allowed set from the key claims, avoiding a server-side lookup while still preventing BOLA:

server.get('/accounts/:id', (req, res, next) => {
  const accountId = req.params.id;
  const keyClaims = verifyScopedKey(req.headers.authorization); // returns { accounts: string[] }
  if (!keyClaims.accounts.includes(accountId)) {
    return res.send(403);
  }
  const account = db.getAccount(accountId);
  res.send(account);
  return next();
});

When using third-party API key management services, leverage their fine-grained permissions to restrict operations per key. Do not assume the key’s scope is enforced by the API gateway alone; enforce checks in your application logic within Restify. Combine this with robust key rotation and revocation procedures to reduce the impact of leaked keys.

middleBrick’s dashboard can help you track these security scores over time and surface misconfigurations tied to authorization. The Pro plan’s continuous monitoring can alert you if a new finding appears on endpoints using API keys, and the GitHub Action can fail builds when risk scores drop below your chosen threshold, helping prevent insecure deployments.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

Can API keys alone prevent BOLA in Restify endpoints?
No. API keys identify the client but do not enforce object-level permissions. You must validate that the requested resource (e.g., account_id) is allowed for the key’s scope on every request.
How does middleBrick detect BOLA when API keys are used?
During unauthenticated scans, middleBrick tests endpoints with valid API keys and attempts to access other objects by manipulating identifiers. It checks whether access is denied for unauthorized objects and reports BOLA when object identifiers are accepted without ownership checks.