HIGH denial of serviceadonisjsdynamodb

Denial Of Service in Adonisjs with Dynamodb

Denial Of Service in Adonisjs with Dynamodb — how this specific combination creates or exposes the vulnerability

AdonisJS, a Node.js web framework, typically interacts with databases through an ORM layer. When using Amazon DynamoDB as the persistence store, the application relies on the AWS SDK for all data operations. A Denial of Service (DoS) risk emerges when requests trigger expensive or unbounded DynamoDB operations without constraints, for example, a query without a limit on a large table or a scan that iterates over many items. These operations consume significant backend read capacity and can saturate the provisioned throughput, causing latency spikes or throttling errors for legitimate traffic. In AdonisJS, route handlers that directly construct query parameters from user input are especially vulnerable if pagination, filtering, or sorting values are not strictly validated.

An attacker can exploit this by sending crafted requests that invoke scan-like behavior or repeated query calls with invalid partition keys, forcing DynamoDB to consume substantial read capacity units. If the AdonisJS service shares a DynamoDB table with other services, noisy endpoints can indirectly degrade performance for unrelated components. Unauthenticated endpoints that perform heavy data retrieval amplify the issue because there is no caller identity to apply per-user quotas. The combination of AdonisJS routing and DynamoDB’s provisioned capacity model means that missing rate controls and missing request validation can quickly turn into availability issues, aligning with the MiddleBrick category of Rate Limiting and BFLA/Privilege Escalation checks.

Consider an endpoint that accepts query parameters for filtering and sorting without server-side limits:

// routes.ts
Route.get('/users', async ({ request }) => {
  const { status, sortBy, order } = request.qs()
  // Potentially unbounded query if client supplies extreme values
  const params = {
    TableName: 'users',
    IndexName: status ? 'status-index' : undefined,
    KeyConditionExpression: status ? 'status = :status' : undefined,
    ExpressionAttributeValues: status ? { ':status': status } : undefined,
    Limit: 1000, // not enforced server-side
    ScanIndexForward: order === 'asc',
  }
  const result = await DynamoDBClient.send(new QueryCommand(params))
  return result.Items
})

If a client supplies an invalid status that does not exist, DynamoDB may still perform a full partition scan within the partition, consuming read capacity. Without strict validation of limit, sortBy, and order, the handler allows resource-intensive patterns typical in BFLA/Privilege Escalation scenarios where higher-than-expected throughput is requested. The scan’s unauthenticated nature means no user context is available to apply tenant-aware throttling, increasing exposure.

Dynamodb-Specific Remediation in Adonisjs — concrete code fixes

To mitigate DoS risks when using DynamoDB with AdonisJS, enforce strict validation, server-side limits, and defensive patterns in route handlers. Begin by validating and sanitizing all incoming query parameters, and apply hard caps on page size to prevent unbounded scans or queries. Use explicit key conditions and avoid scan operations in production code; prefer query with a partition key that is scoped to the requesting tenant or user where feasible.

Implement robust error handling to catch DynamoDB-specific exceptions such as ProvisionedThroughputExceededException and return appropriate HTTP 429 responses rather than allowing cascading failures. Introduce lightweight per-request rate tracking using in-memory or Redis-backed counters keyed by endpoint and, if available, tenant or API key to prevent a single client from exhausting shared capacity.

Below is a concrete, defensive implementation in AdonisJS that incorporates these practices:

// controllers/UsersController.ts
import { schema } from '@ioc:AdonisJS/Core/Validator'
import { DynamoDBClient, QueryCommand, ScanCommand } from '@aws-sdk/client-dynamodb'

const USERS_TABLE = 'users'
const MAX_LIMIT = 50

export default class UsersController {
  private readonly ddb = new DynamoDBClient({})

  async index() {
    const querySchema = schema.create({
      status: schema.string.optional({}, [rules.alpha()]),
      sortBy: schema.optional(schema.union([schema.literal('name'), schema.literal('createdAt')]), {}, ['trim']),
      order: schema.optional(schema.union([schema.literal('asc'), schema.literal('desc')]), {}, ['trim']),
      limit: schema.number.optional({ range: { max: MAX_LIMIT } }),
    })

    const payload = await request.validate({ schema: querySchema })
    const limit = Math.min(payload.limit ?? 10, MAX_LIMIT)

    // Prefer query over scan; ensure partition key is present
    if (payload.status) {
      const params = {
        TableName: USERS_TABLE,
        IndexName: 'status-index',
        KeyConditionExpression: 'status = :status',
        ExpressionAttributeValues: { ':status': { S: payload.status } },
        Limit: limit,
        ScanIndexForward: (payload.order ?? 'asc') === 'asc',
      }
      const command = new QueryCommand(params)
      const result = await this.ddb.send(command)
      return result.Items || []
    }

    // Fallback to a highly constrained scan only when absolutely necessary
    const scanParams = {
      TableName: USERS_TABLE,
      Limit: limit,
    }
    const scanCommand = new ScanCommand(scanParams)
    const scanResult = await this.ddb.send(scanCommand)
    return scanResult.Items || []
  }
}

For broader protection, configure the MiddleBrick CLI scan to validate these patterns against your unauthenticated attack surface. The tool can surface missing rate limits and over-permissive query parameters, helping you address DoS exposure before deployment. With the Pro plan, you can enable continuous monitoring so that changes to route handlers or DynamoDB key schema trigger scans on a configurable schedule, keeping availability risks visible in your CI/CD pipeline.

Related CWEs: resourceConsumption

CWE IDNameSeverity
CWE-400Uncontrolled Resource Consumption HIGH
CWE-770Allocation of Resources Without Limits MEDIUM
CWE-799Improper Control of Interaction Frequency MEDIUM
CWE-835Infinite Loop HIGH
CWE-1050Excessive Platform Resource Consumption MEDIUM

Frequently Asked Questions

How can I prevent DynamoDB from becoming a DoS vector in AdonisJS?
Validate and cap all query parameters, avoid scans in favor of targeted queries, implement server-side rate limits, and handle throughput exceptions gracefully with 429 responses.
Does MiddleBrick automatically fix DoS findings in AdonisJS with DynamoDB?
No. MiddleBrick detects and reports findings with remediation guidance; it does not fix, patch, or block. Use the provided guidance to update validation, limits, and error handling in your AdonisJS routes.