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 ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion 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?
Can DynamoDB's encryption at rest protect against data exposure?
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.