HIGH prototype pollutionadonisjsdynamodb

Prototype Pollution in Adonisjs with Dynamodb

Prototype Pollution in Adonisjs with Dynamodb — how this specific combination creates or exposes the vulnerability

Prototype pollution in AdonisJS when interacting with DynamoDB typically occurs via unchecked user input that is merged into configuration objects, request context, or query-building helpers. Because AdonisJS is a Node.js framework, JavaScript prototype manipulation can affect shared objects if user-controlled keys are copied into objects used across request boundaries or into parameters passed to the AWS SDK.

DynamoDB usage in AdonisJS often involves constructing query parameters (e.g., KeyConditionExpression, FilterExpression, or client calls like get and query) from request data. If an attacker can inject properties such as __proto__, constructor, or prototype into those parameter objects, and those objects are later reused or shallow-copied, the pollution can lead to unexpected behavior, including overwriting defaults or causing unintended type coercions in expression building.

Consider an endpoint that builds a DynamoDB get request from URL parameters:

// Risky: directly using request params to form the Key object
const getUser = async ({ request, response }) => {
  const { userId } = request.params();
  const extra = request.only(['sortKey', 'indexName']);
  const key = { ...userId, ...extra };
  const dynamo = use('Adonis/Addons/DynamoDB');
  const result = await dynamo.get({
    TableName: 'Users',
    Key: key,
  });
  response.send(result);
};

If an attacker sends userId={"S":"alice","__proto__":{"isAdmin":true}} and the merging logic is shallow, the resulting key may carry polluted properties. While DynamoDB’s document structure does not execute JavaScript, the polluted object could affect how AdonisJS builds the request, potentially bypassing intended validation or altering expression construction. Additionally, if the same helper functions or parameter builders are reused across requests (e.g., cached expression templates), prototype pollution may affect subsequent calls, leading to BOLA/IDOR-like logic flaws where one user’s data becomes accessible to another.

The 12 security checks in middleBrick exercise this scenario by injecting probes into input fields that feed DynamoDB operations. It inspects whether untrusted keys reach query construction, checks for missing type validation on expression parameters, and verifies that runtime behavior does not expose unintended data paths. For LLM-specific concerns, it also checks whether model outputs might inadvertently reveal how injected properties could influence downstream logic, though the scanner does not remediate — it reports findings with guidance.

To map this to real-world references, consider a chain where prototype pollution leads to a BOLA bypass (e.g., KeyConditionExpression being altered to match a different partition key), potentially exposing another user’s item. This aligns with OWASP API Top 10:2023 —2 (Broken Object Level Authorization) when pollution changes authorization checks, and CWE-1321 (Improper Control of Modification of Object Prototype). middleBrick’s cross-referencing of spec definitions with runtime findings helps highlight such mismatches between declared and actual behavior.

Dynamodb-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on strict input validation, deep sanitization of objects used in DynamoDB parameters, and avoiding shared mutable state. In AdonisJS, apply validation rules to all user-supplied data before it reaches DynamoDB calls, and ensure parameter construction does not merge raw request objects directly.

1. Validate and whitelist allowed fields for DynamoDB operations. Use AdonisJS schema validation to reject unexpected keys, including prototype pollution vectors like __proto__, constructor, and prototype.

import { schema, rules } from '@ioc:Adonis/Core/Validator';

const userSchema = schema.create({
  userId: schema.string({ trim: true }),
  sortKey: schema.string.optional(),
  // Explicitly disallow prototype pollution keys
  indexName: schema.string.optional([rules.maxLength(255)]),
});

export const getUserValidator = (payload) => {
  return schema.validate({ schema: userSchema, data: payload });
};

2. Build DynamoDB parameters using controlled, sanitized values rather than merging raw input. For example, construct the Key explicitly:

const getUser = async ({ request, response }) => {
  const { userId } = request.params();
  // Validate first
  const validated = await getUserValidator(request.all());
  // Explicit key construction — no spreading of untrusted input
  const key = {
    PK: { S: validated.userId },
    SK: { S: validated.sortKey || 'PROFILE' },
  };
  const dynamo = use('Adonis/Addons/DynamoDB');
  const result = await dynamo.get({
    TableName: 'Users',
    Key: key,
  });
  response.send(result);
};

3. When using expressions, avoid injecting user input directly into expression attribute names or values without escaping. Use placeholder syntax and attribute value mapping:

const queryUsers = async ({ request, response }) => {
  const { prefix } = request.qs();
  // Sanitize prefix — allow only alphanumeric and underscore
  if (!/^[a-zA-Z0-9_]+$/.test(prefix)) {
    return response.badRequest({ error: 'Invalid prefix' });
  }
  const dynamo = use('Adonis/Addons/DynamoDB');
  const params = {
    TableName: 'Logs',
    FilterExpression: '#status = :status_val',
    ExpressionAttributeNames: {
      '#status': 'status',
    },
    ExpressionAttributeValues: {
      ':status_val': { S: prefix },
    },
  };
  const result = await dynamo.scan(params);
  response.send(result);
};

4. For the middleBrick scans, ensure that your API endpoints pass its checks by avoiding dynamic construction of KeyConditionExpression or FilterExpression from concatenated user strings without strict allowlisting. middleBrick’s dashboard and CLI can be integrated into your workflow: use middlebrick scan <url> to validate your endpoints, and if you have the Pro plan, enable continuous monitoring so future changes are flagged before deployment.

5. If you use the GitHub Action, set a threshold to fail builds when risk scores degrade, and if you rely on the MCP Server, scan APIs directly from your IDE during development. These integrations do not alter runtime behavior but help catch regressions that could reintroduce prototype pollution opportunities.

Finally, remember that DynamoDB itself does not interpret JavaScript prototypes; the risk is in how polluted objects affect request construction, authorization checks, or expression assembly within AdonisJS. Remediation is about input hygiene and disciplined parameter building, not about changing the database layer.

Frequently Asked Questions

Does middleBrick fix prototype pollution vulnerabilities in AdonisJS?
No. middleBrick detects and reports findings with remediation guidance; it does not fix, patch, or block vulnerabilities. You must apply the fixes in your code.
Can the LLM/AI security checks in middleBrick detect prototype pollution risks?
The LLM/AI checks focus on prompt injection, system prompt leakage, output scanning, and excessive agency patterns. Prototype pollution is covered by the standard 12 security checks, not by LLM-specific probes.