HIGH data exposuredynamodb

Data Exposure in Dynamodb

How Data Exposure Manifests in Dynamodb

Detecting data exposure in DynamoDB requires examining both configuration and runtime behavior. The most effective approach combines static analysis of IAM policies with dynamic scanning of table structures and query patterns.

middleBrick's DynamoDB scanning specifically targets these exposure patterns. The scanner examines your table's IAM policies to identify overly permissive permissions, checking for wildcard actions and resources that could allow unauthorized data access. It analyzes your table's key schema to identify sensitive attributes used as primary or sort keys.

The scanner also detects global secondary indexes on sensitive attributes. For a table with user data, middleBrick identifies if you have GSIs on fields like ssn, credit_card, or phone_number, which create additional queryable surfaces for that sensitive data.

middleBrick tests for scan operation vulnerabilities by analyzing your query patterns. It identifies code that performs unfiltered Scan operations, which expose all table data to the scanning process. The scanner flags patterns like Scan without FilterExpression or with overly broad filters.

The tool also checks for cross-account exposure by examining resource-based policies on your tables. It identifies policies that grant access to external AWS accounts or public access, flagging potential data leakage scenarios.

For LLM/AI security, middleBrick specifically tests for prompt injection vulnerabilities that could expose DynamoDB data through AI interfaces. It checks if your application's AI endpoints can be manipulated to execute unauthorized Query or GetItem operations on DynamoDB tables.

# Using middleBrick CLI to scan DynamoDB endpoints
middlebrick scan https://dynamodb.us-east-1.amazonaws.com

# Output includes:
# - IAM Policy Analysis
# - Key Schema Review
# - GSI Exposure Report
# - Query Pattern Analysis
# - Cross-Account Access Check

The scanner provides a security score (0-100) with letter grades and identifies specific findings with severity levels. For DynamoDB data exposure, findings typically include "Sensitive data in primary key", "Unrestricted IAM permissions", "GSI on PII", and "Unfiltered scan operations".

Dynamodb-Specific Remediation

Remediating DynamoDB data exposure requires a defense-in-depth approach that combines proper IAM policies, careful schema design, and secure query patterns. The following code examples demonstrate DynamoDB-native solutions to common exposure issues.

First, implement principle of least privilege in your IAM policies. Instead of wildcard permissions, specify exact actions and resources needed:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:Query",
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/Users"
    }
  ]
}

Second, avoid using sensitive data as partition keys. Instead, use surrogate keys and store sensitive data in attributes with proper encryption:

// Vulnerable: Using email as partition key
const vulnerableParams = {
  TableName: 'Users',
  Key: { email: '[email protected]' }
};

// Secure: Using UUID as partition key, email as attribute
const secureParams = {
  TableName: 'Users',
  Item: {
    userId: '550e8400-e29b-41d4-a716-446655440000',
    email: '[email protected]',
    ssn: '123-45-6789' // Encrypted at rest
  }
};

Third, encrypt sensitive attributes at rest using DynamoDB's encryption features. For server-side encryption with customer-managed keys:

const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient({
  region: 'us-east-1'
});

// Encrypt sensitive data before storing
const encryptSSN = (ssn) => {
  // Implement encryption logic
  return encryptedSSN;
};

const storeUser = async (user) => {
  const params = {
    TableName: 'Users',
    Item: {
      userId: user.userId,
      email: user.email,
      ssn: encryptSSN(user.ssn), // Encrypted
      creditCard: encryptCC(user.creditCard) // Encrypted
    }
  };
  
  await documentClient.put(params).promise();
};

Fourth, implement proper filtering to prevent scan operations from exposing all data:

// Vulnerable: Unfiltered scan
const vulnerableScan = async () => {
  const params = {
    TableName: 'Users'
  };
  return await documentClient.scan(params).promise();
};

// Secure: Filtered query
const secureQuery = async (email) => {
  const params = {
    TableName: 'Users',
    KeyConditionExpression: 'email = :email',
    ExpressionAttributeValues: {
      ':email': email
    }
  };
  return await documentClient.query(params).promise();
};

Fifth, review and remove unnecessary global secondary indexes. Only create GSIs on attributes that need to be queryable:

// Before: GSI on sensitive attribute
const before = {
  TableName: 'Users',
  GlobalSecondaryIndexes: [{
    IndexName: 'ssn-index',
    KeySchema: [
      { AttributeName: 'ssn', KeyType: 'HASH' }
    ]
  }]
};

// After: Remove sensitive GSIs
const after = {
  TableName: 'Users',
  GlobalSecondaryIndexes: []
};

Finally, implement audit logging to detect unauthorized access attempts. Use DynamoDB Streams with Lambda to log all access attempts to sensitive data:

const auditLog = async (event) => {
  const record = event.Records[0].dynamodb;
  
  if (record.eventName === 'MODIFY' || record.eventName === 'INSERT') {
    const item = record.NewImage;
    
    // Check for sensitive data access
    if (item.ssn || item.creditCard) {
      await logToAuditService({
        action: record.eventName,
        userId: item.userId,
        timestamp: record.approximateCreationDateTime,
        accessedFields: Object.keys(item)
      });
    }
  }
};

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

How does DynamoDB's NoSQL architecture create unique data exposure risks compared to SQL databases?
DynamoDB's schemaless design and lack of built-in access controls create exposure patterns unique to NoSQL. Unlike SQL's row-level permissions and complex JOIN operations, DynamoDB exposes entire items through partition keys, and GSIs create additional queryable surfaces. The absence of foreign key constraints means data relationships are application-managed, increasing the risk of improper access control. Additionally, DynamoDB's scan operations read entire tables into memory, potentially exposing all data during filtering operations.
Can DynamoDB's encryption at rest protect against data exposure?
DynamoDB's server-side encryption protects data from physical theft and unauthorized AWS access, but it doesn't prevent exposure through IAM permissions or application logic flaws. If your IAM policy allows GetItem on a table, encryption at rest won't stop that operation from returning sensitive data. Encryption is one layer of defense, but proper IAM policies, careful schema design, and secure query patterns are equally important for preventing data exposure.