HIGH out of bounds readfeathersjsdynamodb

Out Of Bounds Read in Feathersjs with Dynamodb

Out Of Bounds Read in Feathersjs with Dynamodb — how this specific combination creates or exposes the vulnerability

An Out Of Bounds Read in a Feathers.js service backed by DynamoDB typically arises when the service layer uses user-controlled pagination or filtering parameters to access items in a collection without validating range constraints or record existence. Feathers.js does not inherently protect against logical index errors; it passes query parameters such as $skip, $limit, and custom filters to the adapter, and the DynamoDB adapter translates these into Low-Level API operations like Query or Scan. If the application requests a page beyond available records, the adapter may produce an empty result set, but mishandled offsets or miscalculated ExclusiveStartKey values can lead to attempts to read non-existent segments of the dataset.

Consider a service that exposes a paginated endpoint using a numeric page parameter supplied directly by the client:

app.use('/items', new DynamoDBAdapter({ tableName: 'Items' }));
app.service('items').hooks({
  before: {
    find: context => {
      const page = Number(context.params.query.page) || 1;
      const limit = 20;
      // Potential out-of-bounds calculation if page is large
      context.params.query.$skip = (page - 1) * limit;
      delete context.params.query.page;
    }
  }
});

If the dataset contains fewer than ((page - 1) * limit) records, the $skip value may exceed the total number of items. With DynamoDB, a Query with an excessive Skip beyond the result set yields an empty response, but the application logic that interprets the response may assume a valid item exists at that index, leading to an out-of-bounds read when accessing array positions or related in-memory structures. This becomes more pronounced when combining $skip with inconsistent sorting, because DynamoDB does not guarantee a stable order without an explicit ScanIndexForward and a deterministic sort key.

Additionally, custom services that manually retrieve a record by an ID derived from user input without verifying existence can trigger out-of-bounds reads at the application level. For example:

app.service('profiles').hooks({
  before: {
    get: context => {
      const id = context.id;
      const params = {
        Key: { id: { S: id } },
        TableName: 'Profiles'
      };
      return context.app.get('dynamodb').get(params).promise()
        .then(data => {
          if (!data.Item) {
            throw new errors.NotFound('Profile not found');
          }
          // If downstream code assumes data.Item contains expected nested arrays
          // and accesses index [0] without checking length, an out-of-bounds read may occur
          const firstTag = data.Item.tags[0];
          return data.Item;
        });
    }
  }
});

In this pattern, if the tags attribute is missing or an empty list, accessing data.Item.tags[0] can result in undefined or unexpected behavior, representing an out-of-bounds read within the application logic. Because the DynamoDB response is trusted implicitly, validation of array bounds is skipped. The combination of unchecked pagination parameters and unvalidated assumptions about the structure of retrieved items creates the conditions for this class of vulnerability.

Dynamodb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on validating inputs before they are translated into DynamoDB operations and defensively handling responses. Always enforce strict type checks, range validation for numeric parameters, and existence checks for retrieved data before accessing nested structures.

For paginated endpoints, replace page-based arithmetic with cursor-based pagination using DynamoDB's ExclusiveStartKey and ensure Limit is bounded:

app.use('/items', new DynamoDBAdapter({ tableName: 'Items' }));
app.service('items').hooks({
  before: {
    find: context => {
      const query = context.params.query;
      const limit = Math.min(Number(query.limit) || 20, 100);
      const token = query.nextToken || null;
      const filter = query.filter ? JSON.parse(query.filter) : {};
      context.params.query.$limit = limit;
      if (token) {
        context.params.query.$exclusiveStartKey = token;
      }
      delete context.params.query.nextToken;
      delete query.filter;
    }
  }
});

This approach avoids large offset calculations and constrains the maximum page size, reducing the likelihood of requesting beyond available data. When processing the response, check array lengths before indexing:

const result = await context.app.service('profiles').get(id);
if (result && result.tags && result.tags.length > 0) {
  const firstTag = result.tags[0];
} else {
  // Handle missing or empty tags safely
  const firstTag = null;
}

Implement explicit existence and type checks for items retrieved by ID:

app.service('profiles').hooks({
  before: {
    get: async context => {
      const params = {
        Key: { id: { S: String(context.id) } },
        TableName: 'Profiles'
      };
      const data = await context.app.get('dynamodb').get(params).promise();
      if (!data.Item) {
        throw new errors.NotFound('Profile not found');
      }
      // Validate expected structure before access
      const tags = Array.isArray(data.Item.tags) ? data.Item.tags : [];
      const firstTag = tags.length > 0 ? tags[0] : null;
      return { ...data.Item, firstTag };
    }
  }
});

Additionally, use middleware to sanitize and normalize query parameters, and apply schema validation (for example with JSON Schema) on the shape of DynamoDB responses before they reach downstream consumers. This ensures that assumptions about nested arrays or required fields are verified, preventing out-of-bounds reads caused by malformed or unexpected data.

Frequently Asked Questions

How does middleBrick detect Out Of Bounds Read risks in a Feathersjs + DynamoDB setup?
middleBrick scans the unauthenticated attack surface and maps findings to the OpenAPI/Swagger spec with full $ref resolution, correlating runtime behavior with defined operations to identify unsafe pagination, missing validation, and assumptions about response structure that can lead to out-of-bounds reads.
Can the free plan of middleBrick scan a Feathersjs API connected to DynamoDB?
Yes; the free plan allows 3 scans per month and supports any public endpoint, including Feathersjs services backed by DynamoDB, without requiring credentials or agents.