Cors Wildcard in Hapi with Dynamodb
Cors Wildcard in Hapi with DynamoDB — how this specific combination creates or exposes the vulnerability
A CORS wildcard (Access-Control-Allow-Origin: *) in a Hapi server that also interacts with DynamoDB can unintentionally expose sensitive data and amplify authorization flaws such as BOLA/IDOR. When the Hapi route handlers serve requests from a wildcard, any origin can make authenticated or unauthenticated requests and inspect responses that include data retrieved from DynamoDB. Because responses may contain user-specific items from DynamoDB (e.g., user IDs in partition keys), the wildcard allows any site to read those results if other protections (like proper ownership checks) are missing or misconfigured.
In a black-box scan, middleBrick tests the unauthenticated attack surface and flags a CORS wildcard as a high-severity finding when responses include sensitive DynamoDB data or when preflight responses expose headers that enable cross-origin abuse. Attack patterns include reading other users’ records via manipulated identifiers, leveraging CORS to facilitate SSRF-assisted data access, or using the wildcard to hide the true origin of malicious requests. The combination is risky because CORS is a browser-enforced mechanism; a wildcard paired with overly permissive routes can bypass same-origin policies that applications rely on to isolate DynamoDB-backed resources.
Consider a Hapi route that queries DynamoDB using a user-provided userId without verifying that the authenticated actor matches that ID. With a wildcard, any origin can send requests and observe whether different userId values return data, enabling enumeration or indirect data exfiltration. middleBrick’s checks for BOLA/IDOR and CORS run in parallel, and the tool surfaces per-category breakdowns so you can see how a wildcard contributes to a higher risk score.
Additionally, response headers set by Hapi may include DynamoDB metadata (such as custom headers or timing differences) that, when combined with a wildcard, give attackers more information for further attacks. The scanner tests input validation and rate limiting alongside CORS to determine whether overly broad origins interact with insufficient checks on identifiers or authorization. Remediation involves tightening CORS origins, enforcing strict authorization on each DynamoDB request, and ensuring responses do not leak information that could be leveraged cross-origin.
DynamoDB-Specific Remediation in Hapi — concrete code fixes
To remediate CORS issues while safely using DynamoDB in Hapi, configure CORS to allow only trusted origins and enforce ownership checks on every database call. Below are concrete, working examples that combine Hapi route definitions with the AWS SDK for JavaScript (v3) to implement secure patterns.
1. Configure strict CORS in Hapi
Set cors options on your Hapi server to a specific origin instead of *. Include necessary methods and headers, and avoid exposing sensitive headers to untrusted origins.
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 4000,
host: 'localhost',
routes: {
cors: {
origin: ['https://app.example.com', 'https://admin.example.com'],
additionalHeaders: ['authorization', 'content-type'],
additionalExposedHeaders: ['x-request-id'],
credentials: true
}
}
});
server.route({
method: 'GET',
path: '/items/{id}',
handler: async (request) => {
// Authorization and ownership checks should happen here
return getDynamoItem(request.params.id, request.auth.credentials);
}
});
await server.start();
};
init();
2. DynamoDB get with ownership validation
Before fetching an item from DynamoDB, confirm the requesting user has permission to access it. Use the AWS SDK for JavaScript (v3) and pass the user’s identity from your auth layer.
const { DynamoDBClient, GetItemCommand } = require('@aws-sdk/client-dynamodb');
const ddb = new DynamoDBClient({ region: 'us-east-1' });
async function getDynamoItem(id, userCredentials) {
if (!userCredentials || !userCredentials.sub) {
throw new Error('Unauthorized');
}
// Assume userCredentials.sub holds the user ID from your auth provider
const command = new GetItemCommand({
TableName: process.env.DYNAMODB_TABLE,
Key: {
pk: { S: `USER#${userCredentials.sub}` },
sk: { S: `ITEM#${id}` }
}
});
const response = await ddb.send(command);
if (!response.Item) {
throw new Error('Not found');
}
// Ensure the item belongs to the requesting user
if (response.Item.sk.S !== `ITEM#${id}`) {
throw new Error('Forbidden');
}
return {
id: response.Item.sk.S,
data: response.Item.data?.S
};
}
3. DynamoDB query with user-scoped partition key
Design your DynamoDB access patterns so queries are scoped to the authenticated user’s partition key, preventing horizontal privilege escalation.
const { DynamoDBClient, QueryCommand } = require('@aws-sdk/client-dynamodb');
const ddb = new DynamoDBClient({ region: 'us-east-1' });
async function listUserItems(userId) {
const command = new QueryCommand({
TableName: process.env.DYNAMODB_TABLE,
KeyConditionExpression: 'pk = :pk',
ExpressionAttributeValues: {
':pk': { S: `USER#${userId}` }
}
});
const response = await ddb.send(command);
return response.Items.map(item => ({
id: item.sk.S,
name: item.name?.S
}));
}
4. Centralized authorization helper
Use a shared authorization function to validate ownership for both get and list operations, keeping DynamoDB access patterns consistent and auditable.
async function authorizeItemAccess(requestItemId, user) {
// Implement your policy logic here, e.g., ensure requestItemId maps to user
if (!requestItemId || !user.sub) {
return false;
}
// Example: item ID must encode user ID
return requestItemId.startsWith(`item-${user.sub}-`);
}
By combining strict origin policies in Hapi with ownership checks on every DynamoDB call, you reduce the risk that a CORS wildcard leads to unauthorized data access. middleBrick’s scans can validate these configurations in runtime tests and provide prioritized findings with remediation guidance to help you address issues systematically.
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 |