HIGH data exposurehapidynamodb

Data Exposure in Hapi with Dynamodb

Data Exposure in Hapi with Dynamodb — how this specific combination creates or exposes the vulnerability

When building Hapi serverless functions or endpoints that interact with DynamoDB, data exposure can occur through misconfigured access patterns, overly permissive IAM policies, and insufficient runtime validation. In this combination, the API surface often includes DynamoDB operations such as GetItem, Scan, or Query that may inadvertently return sensitive attributes or entire items due to projection expressions or missing attribute filters.

Hapi does not enforce data filtering by default; developers must explicitly shape responses. If a route handler passes raw DynamoDB output to the response, fields such as password_hash, api_key, or personal identifiable information (PII) can be exposed. A common pattern is using documentClient.get(params, callback) without trimming non-essential attributes, which can expose internal metadata or sensitive columns stored alongside business data.

Additionally, DynamoDB’s flexible schema can lead to inconsistent item shapes. If a route expects a subset of attributes but the item contains extra sensitive fields (for example, ssn or credit_card), missing schema validation in Hapi increases the risk of accidental exposure. Route-level validation using Joi in Hapi can mitigate this, but if validation rules are incomplete or loosely defined, sensitive data can pass through unchecked.

Another vector involves scan and query operations without server-side filtering. Developers sometimes use Scan to retrieve items and then apply client-side filtering, which is inefficient and risky because the scan returns entire items. An attacker who compromises the API endpoint may receive more data than intended, including credentials or tokens stored in DynamoDB item attributes.

Error handling also plays a role. Misconfigured error responses can leak stack traces or internal DynamoDB messages that reveal table or index names, helping an attacker refine exploitation. In a Hapi service, uncaught exceptions from DynamoDB may expose sensitive context if responses are not sanitized before reaching the client.

To reduce data exposure in Hapi with DynamoDB, adopt explicit attribute selection, enforce strict Joi validation, apply server-side filtering where possible, and sanitize errors. These practices limit the data returned and ensure that only intended attributes traverse the API layer, reducing the impact of misconfigurations or injection attempts covered by checks such as those in middleBrick’s Data Exposure category.

Dynamodb-Specific Remediation in Hapi — concrete code fixes

Remediation focuses on controlling what DynamoDB returns and ensuring Hapi responses contain only necessary data. Use projection expressions in GetItem and Query to limit attributes, and avoid Scan unless absolutely necessary. Validate and transform DynamoDB output before sending it to the client.

Example 1: Safe GetItem with projection and validation

const Hapi = require('@hapi/hapi');
const AWS = require('aws-sdk');
const Joi = require('joi');

const server = Hapi.server({ port: 4000 });
const docClient = new AWS.DynamoDB.DocumentClient();

const userSchema = Joi.object({
  userId: Joi.string().required(),
  email: Joi.string().email().required(),
  name: Joi.string().required()
});

server.route({
  method: 'GET',
  path: '/users/{id}',
  handler: async (request) => {
    const params = {
      TableName: process.env.USERS_TABLE,
      Key: { userId: request.params.id },
      // Limit returned attributes to reduce exposure
      ProjectionExpression: 'userId, email, name'
    };

    const data = await docClient.get(params).promise();
    if (!data.Item) {
      throw Boom.notFound('User not found');
    }

    // Validate shape before returning
    const { error, value } = userSchema.validate(data.Item);
    if (error) {
      throw Boom.badImplementation('Data validation failed');
    }
    return value;
  }
});

Example 2: Query with server-side filtering and strict response shaping

server.route({
  method: 'GET',
  path: '/orders',
  handler: async (request) => {
    const params = {
      TableName: 'Orders',
      IndexName: 'UserIdIndex',
      KeyConditionExpression: 'userId = :uid',
      FilterExpression: 'orderStatus = :status',
      ExpressionAttributeValues: {
        ':uid': request.query.userId,
        ':status': 'completed'
      },
      // Only fetch required fields
      ProjectionExpression: 'orderId, total, createdAt'
    };

    const data = await docClient.query(params).promise();
    // Shape response to exclude any reserved or sensitive metadata
    return data.Items.map(item => ({
      orderId: item.orderId,
      total: item.total,
      createdAt: item.createdAt
    }));
  }
});

Example 3: Avoid Scan; use Query with pagination and attribute selection

server.route({
  method: 'GET',
  path: '/search',
  handler: async (request) => {
    const params = {
      TableName: 'Products',
      IndexName: 'CategoryIndex',
      KeyConditionExpression: 'category = :cat',
      Select: 'SPECIFIC_ATTRIBUTES',
      ProjectionExpression: 'productId, name, price',
      Limit: 20
    };

    const data = await docClient.query(params).promise();
    return data.Items;
  }
});

IAM and configuration best practices

  • Apply least-privilege IAM policies to the Lambda/role used by Hapi, allowing only needed DynamoDB actions on specific table resources.
  • Enable DynamoDB encryption at rest and use VPC endpoints or AWS PrivateLink where applicable to reduce exposure in transit.
  • Rotate credentials and use AWS SDK’s default credential provider chain; avoid embedding keys in code or environment variables without encryption.
  • Log and monitor access patterns; use AWS CloudTrail and DynamoDB Streams cautiously, ensuring logs themselves do not expose sensitive fields.

These concrete fixes help ensure that Hapi services handling DynamoDB responses adhere to the principle of least disclosure, reducing data exposure risks while maintaining functionality.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Why does using Scan in Hapi with DynamoDB increase data exposure risk?
Scan reads entire items and returns all attributes unless a ProjectionExpression is used. Without explicit attribute selection, sensitive fields can be exposed. Prefer Query with indexed attributes and projection to limit returned data.
How can Joi validation in Hapi help prevent data exposure with DynamoDB?
Joi enforces a strict schema so only expected attributes are processed and returned. This prevents extra sensitive fields in DynamoDB items from unintentionally appearing in API responses.