HIGH bola idorsailsdynamodb

Bola Idor in Sails with Dynamodb

Bola Idor in Sails with Dynamodb — how this specific combination creates or exposes the vulnerability

Broken Object Level Authorization (BOLA) occurs when an API exposes one user’s object to another user because the application fails to enforce ownership or authorization checks at the object level. In a Sails.js application using Amazon DynamoDB as the primary datastore, this risk arises when controllers look up records by a client-supplied identifier (e.g., a numeric or string ID) without verifying that the authenticated subject has permission to access that record.

Consider a Sails controller that retrieves a user profile by ID directly from DynamoDB:

module.exports = {
  async findById(req, res) {
    const { id } = req.params.all();
    const result = await dynamodb.get({
      TableName: 'profiles',
      Key: { profileId: id },
    }).promise();
    return res.ok(result.Item);
  },
};

If the endpoint is exposed as /profile/:id and the caller provides a different profile ID, the controller returns that profile without confirming the caller owns it. In DynamoDB terms, there is no secondary index or attribute check tying the profile to the requester’s user ID. This is a classic BOLA pattern: the object identifier is user-controlled, but authorization is not validated against the authenticated subject’s identity.

In Sails, developers often rely on implicit assumptions about ownership (e.g., associating records with a user ID) but omit explicit checks in each action. With DynamoDB, there is no row-level security; it is a key-value store that returns items only when the exact key is supplied. If the application key is derived from user input without cross-referencing the authenticated user’s ID, BOLA is likely present. For example, using a UUID as a profile key does not inherently prevent BOLA; without an additional filter on the requester’s user ID, an attacker can enumerate or access other users’ profiles by guessing or iterating IDs.

Moreover, Sails blueprints can inadvertently expose BOLA if configured to allow direct lookup by ID without scoping. When using the built-in REST blueprint routes, developers might assume that policies or model associations enforce ownership, but if those safeguards are incomplete or disabled, DynamoDB returns the requested item regardless of context. The unauthenticated attack surface includes endpoints that accept identifiers without validating them against the caller’s identity stored in the session or token, making the API susceptible to horizontal privilege escalation where one user accesses another’s data.

Dynamodb-Specific Remediation in Sails — concrete code fixes

To remediate BOLA in Sails with DynamoDB, always include the authenticated subject’s identifier as part of the DynamoDB key or as a filter condition that cannot be bypassed. This ensures that even if an attacker supplies a different object ID, the query will either return no results or return only data belonging to the authenticated user.

One approach is to design DynamoDB tables with a composite primary key that incorporates the user ID. For example, use a partition key composed of userId#profileId or maintain a global secondary index (GSI) that indexes profiles by user. This allows efficient queries scoped to a specific user without scanning the entire table.

Below is a secure Sails controller implementation that retrieves a profile only if it belongs to the authenticated user. It assumes the authenticated user’s ID is available via req.me.id, which is typically populated by an authentication policy:

module.exports = {
  async findOwn(req, res) {
    const userId = req.me.id; // authenticated subject from policy
    const { id } = req.params.all();

    const result = await dynamodb.get({
      TableName: 'profiles',
      Key: {
        pk: `USER#${userId}`,
        sk: `PROFILE#${id}`,
      },
    }).promise();

    if (!result.Item) {
      return res.notFound();
    }

    // Ensure the item’s user context matches the requester
    if (result.Item.userId !== userId) {
      return res.forbidden('You do not have permission to access this resource');
    }

    return res.ok(result.Item);
  },
};

When using DynamoDB with sparse indexes or when modeling data for ownership, include the user ID as a sort key or as an indexed attribute. The following example demonstrates querying a profile table with a GSI named UserIdIndex to enforce ownership at the database level:

module.exports = {
  async listForUser(req, res) {
    const userId = req.me.id;

    const result = await dynamodb.query({
      TableName: 'profiles',
      IndexName: 'UserIdIndex',
      KeyConditionExpression: 'userId = :uid',
      ExpressionAttributeValues: {
        ':uid': userId,
      },
    }).promise();

    return res.ok(result.Items);
  },
};

In addition to key design, apply authorization checks in Sails policies to prevent BOLA across all controller actions. A policy can validate that the requested resource ID maps to the authenticated user before allowing the request to reach the controller. Combine this with DynamoDB conditional expressions to ensure updates affect only items belonging to the user, reducing the risk of ID manipulation attacks.

Finally, avoid using sequential or guessable identifiers in URLs. Prefer UUIDs or opaque tokens for object IDs, but remember that obscurity is not a substitute for proper authorization. With DynamoDB, design your access patterns around authenticated queries rather than trusting client-supplied keys alone.

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

How does middleBrick detect BOLA in Sails applications using DynamoDB?
middleBrick performs black-box scanning of the unauthenticated attack surface and, where OpenAPI specs are available, cross-references path parameters and DynamoDB key designs to identify missing ownership checks. It flags endpoints where object identifiers are not scoped to the authenticated subject.
Can middleBrick fix BOLA vulnerabilities in DynamoDB-backed Sails APIs?
middleBrick detects and reports BOLA findings with remediation guidance, but it does not fix, patch, or block issues. Developers must implement scoped queries and authorization checks in Sails controllers and DynamoDB access patterns based on the provided guidance.