Path Traversal in Dynamodb
How Path Traversal Manifests in Dynamodb
Path traversal attacks in DynamoDB typically occur when user-controlled input is used to construct table names, partition keys, or attribute paths without proper validation. Unlike traditional file system path traversal, DynamoDB path traversal exploits the database's flexible schema to access unauthorized data or cause denial of service.
// Vulnerable DynamoDB code with path traversal
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB();
exports.handler = async (event) => {
const tableName = event.queryStringParameters.table || 'default-table';
const userId = event.queryStringParameters.userId;
// Path traversal: attacker can specify any table name
const params = {
TableName: tableName,
Key: { 'user_id': { S: userId } }
};
const result = await dynamodb.getItem(params).promise();
return result;
};
In this example, an attacker can manipulate the table parameter to access any DynamoDB table the IAM role has permissions for. They might use relative paths like ../../sensitive-data or simply enumerate table names to discover the database schema.
Another common pattern involves partition key traversal where user input is concatenated to form keys:
# Vulnerable Python DynamoDB code
import boto3
from boto3.dynamodb.conditions import Key
dynamodb = boto3.resource('dynamodb')
def get_user_data(user_input):
# Path traversal via partition key construction
partition_key = f"users/{user_input}"
table = dynamodb.Table('UserData')
response = table.query(
KeyConditionExpression=Key('partition_key').eq(partition_key)
)
return response['Items']
An attacker could supply user_input values like ../admin or ../config to traverse the logical key space and access unauthorized records.
DynamoDB's JSON document support also enables attribute path traversal:
// Attribute path traversal in DynamoDB DocumentClient
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
async function updateProfile(event) {
const userId = event.userId;
const updatePath = event.updatePath; // User-controlled path
const newValue = event.newValue;
// Vulnerable: arbitrary attribute path traversal
const params = {
TableName: 'Users',
Key: { id: userId },
UpdateExpression: `set ${updatePath} = :val`,
ExpressionAttributeValues: { ':val': newValue }
};
await dynamodb.update(params).promise();
}
Here, an attacker could set updatePath to admin.access or ../../config to modify unauthorized attributes or traverse the object hierarchy.
Dynamodb-Specific Detection
Detecting path traversal in DynamoDB requires examining both the code patterns and the runtime behavior. Static analysis can identify vulnerable code structures, while dynamic scanning can validate the actual attack surface.
Static detection patterns for DynamoDB path traversal:
# Look for DynamoDB operations with user-controlled TableName
# grep -r "TableName.*event\|TableName.*req" --include="*.js" --include="*.py"
# Search for DocumentClient UpdateExpression with variable interpolation
# grep -r "UpdateExpression.*\$\|UpdateExpression.*+" --include="*.js"
# Find partition key construction with string concatenation
# grep -r "KeyConditionExpression.*Key(" --include="*.py"
Dynamic detection with middleBrick specifically tests for DynamoDB path traversal by:
- Scanning API endpoints that accept table names or partition keys
- Testing for directory traversal patterns in DynamoDB-specific parameters
- Analyzing OpenAPI specs for DynamoDB operations with user-controlled inputs
- Checking for excessive permissions that enable table enumeration
- Verifying proper IAM role restrictions on DynamoDB operations
middleBrick's DynamoDB-specific checks include:
{
"dynamodb_path_traversal": {
"enabled": true,
"tests": [
"table_name_parameter_injection",
"partition_key_traversal",
"attribute_path_injection",
"document_client_update_expression",
"iam_permission_analysis"
]
}
}
The scanner tests common traversal patterns like:
GET /api/users?table=../../../../etc/passwd
POST /api/update?path=admin.access
GET /api/data?partition=users/../admin
middleBrick also analyzes the DynamoDB table structure and permissions to identify over-privileged IAM roles that could enable path traversal at scale.
Dynamodb-Specific Remediation
Remediating DynamoDB path traversal requires input validation, least privilege IAM policies, and safe coding practices. Here are specific fixes for DynamoDB applications:
1. Input Validation and Whitelisting:
// Safe DynamoDB table access with validation
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB();
const ALLOWED_TABLES = ['Users', 'Orders', 'Products'];
exports.handler = async (event) => {
const requestedTable = event.queryStringParameters.table;
// Validate table name against whitelist
if (!ALLOWED_TABLES.includes(requestedTable)) {
throw new Error('Invalid table access');
}
const params = {
TableName: requestedTable,
Key: { 'user_id': { S: event.userId } }
};
return await dynamodb.getItem(params).promise();
};
2. Safe Partition Key Construction:
import boto3
from boto3.dynamodb.conditions import Key
import re
def validate_partition_key(key):
# Only allow alphanumeric and underscore
if not re.match(r'^[a-zA-Z0-9_]+$', key):
raise ValueError('Invalid partition key format')
return key
def get_user_data(user_input):
validated_key = validate_partition_key(user_input)
partition_key = f"users/{validated_key}"
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('UserData')
response = table.query(
KeyConditionExpression=Key('partition_key').eq(partition_key)
)
return response['Items']
3. Safe Attribute Path Updates:
// Safe DynamoDB DocumentClient updates
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const ALLOWED_PATHS = ['profile.name', 'profile.email', 'settings.theme'];
async function safeUpdateProfile(event) {
const userId = event.userId;
const updatePath = event.updatePath;
const newValue = event.newValue;
// Validate update path against whitelist
if (!ALLOWED_PATHS.includes(updatePath)) {
throw new Error('Invalid update path');
}
const params = {
TableName: 'Users',
Key: { id: userId },
UpdateExpression: `set ${updatePath} = :val`,
ExpressionAttributeValues: { ':val': newValue }
};
return await dynamodb.update(params).promise();
}
4. Least Privilege IAM Policies:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/Users"
}
]
}
5. middleBrick Integration for Continuous Security:
# GitHub Action for DynamoDB security
name: DynamoDB Security Scan
on:
pull_request:
paths: ['src/**/*.js', 'src/**/*.py']
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install middleBrick
run: npm install -g middlebrick
- name: Scan DynamoDB endpoints
run: middlebrick scan https://api.example.com --output json
- name: Fail on high severity findings
run: |
if [ $(jq '.risk_summary.severity' report.json) == "high" ]; then
exit 1
fi
6. Automated Testing for Path Traversal:
// Test suite for DynamoDB path traversal
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
async function testPathTraversal() {
const testCases = [
{ input: '../admin', expected: false },
{ input: '../../config', expected: false },
{ input: 'valid_table', expected: true }
];
for (const test of testCases) {
try {
const result = await dynamodb.getItem({
TableName: test.input,
Key: { id: 'test' }
}).promise();
if (!test.expected) {
console.error(`Path traversal allowed: ${test.input}`);
}
} catch (error) {
if (test.expected) {
console.error(`Valid access blocked: ${test.input}`);
}
}
}
}
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |