Data Exposure in Chi with Dynamodb
Data Exposure in Chi with Dynamodb — how this specific combination creates or exposes the vulnerability
Data Exposure in the context of Chi using Amazon DynamoDB arises when API endpoints inadvertently return sensitive attributes or entire items that should be restricted. In Chi, developers often model domain entities directly as DynamoDB items, storing fields such as email, internal identifiers, payment metadata, or health-related data. If an endpoint returns a full DynamoDB response without filtering attributes, clients can see values that should remain server-side.
DynamoDB’s schema-less design can amplify this risk: items may contain nested maps or lists that include sensitive keys, and queries or scans that do not explicitly project only safe attributes will return everything. For example, an endpoint that retrieves a user profile might return the full item including email, ssn, or api_key fields because the query did not specify a projection expression. MiddleBrick’s Data Exposure checks detect when responses include known sensitive patterns such as keys named password, token, or PII labels, and when responses contain values that match credit card or email-like formats.
Additionally, DynamoDB conditional expressions or filter expressions that are misconfigured can still allow read access to items that should be invisible to a given role. Consider a query that filters on a partition key correctly but omits a filter on a sensitive attribute; the response may include the item while only a subset of attributes should be surfaced. In Chi, where APIs often compose multiple data sources, a single over-permissive DynamoDB read can expose related data across services. MiddleBrick’s scans cross-reference the OpenAPI specification with runtime responses to highlight mismatches between declared behavior and actual data exposure.
Real-world patterns observed include returning raw DynamoDB JSON that includes type markers (e.g., S, N, BOOL) or returning items with large nested structures. These patterns indicate that the API is exposing internal representation rather than a sanitized contract. The scanner also flags endpoints that lack any server-side field filtering and that return entire items, which is a common root cause of Data Exposure when using DynamoDB in Chi.
Dynamodb-Specific Remediation in Chi — concrete code fixes
To remediate Data Exposure when using DynamoDB in Chi, apply strict attribute filtering on both the query and the response. Use ProjectionExpression to return only necessary attributes, and avoid returning the full item by default. Combine this with a FilterExpression for conditional inclusion, and validate that sensitive fields are omitted from the payload sent to the client.
Example 1: Query with ProjectionExpression
Retrieve only public-safe attributes for a user profile:
const AWS = require('aws-sdk');
const dynamo = new AWS.DynamoDB.DocumentClient();
async function getUserPublicProfile(userId) {
const params = {
TableName: 'Users',
Key: { user_id: userId },
ProjectionExpression: 'user_id, username, created_at',
};
const { Item } = await dynamo.get(params).promise();
return Item; // Contains only user_id, username, created_at
}
Example 2: Query with FilterExpression and safe key names
Ensure that sensitive attributes are not used as map keys and that returned data is limited:
const params = {
TableName: 'Profiles',
KeyConditionExpression: 'pk = :pkval',
FilterExpression': 'attribute_exists(visible) AND visible = :true',
ExpressionAttributeValues: {
':pkval': 'profile#123',
':true': true,
},
ProjectionExpression: 'profile_id, display_name, preferences',
};
const { Items } = await dynamo.query(params).promise();
// Returns only profile_id, display_name, preferences where visible is true
Example 3: BatchGet with ProjectionExpression
When reading multiple items, restrict attributes across the batch:
const params = {
RequestItems: {
Orders: {
Keys: [{ order_id: 'o-001' }, { order_id: 'o-002' }],
ProjectionExpression: 'order_id, total, status',
},
},
};
const { Responses } = await dynamo.batchGet(params).promise();
// Responses.Orders contains only order_id, total, status
Example 4: Avoid returning DynamoDB type markers
When using DocumentClient, ensure that the serialized output does not accidentally expose internal metadata. Always map DocumentClient results to plain objects before sending responses:
function sanitizeForResponse(item) {
return {
userId: item.user_id,
email: item.email,
// Do not forward internal fields like _version or meta
};
}
Additional practices
- Define a denylist of sensitive keys in your schema and enforce server-side field removal before serialization.
- Use IAM policies and resource-based policies to restrict who can call
GetItem,Query, andScanon tables that contain sensitive data. - Validate input keys to prevent accidental exposure via malformed requests that exploit DynamoDB’s attribute name handling.
These changes reduce the attack surface by ensuring only intended data leaves DynamoDB and reaches the Chi API layer, aligning runtime behavior with declared contracts.
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 |