Excessive Data Exposure in Adonisjs with Dynamodb
Excessive Data Exposure in Adonisjs with Dynamodb
Excessive Data Exposure occurs when an API returns more data than necessary for a given operation, and the Adonisjs + DynamoDB combination can unintentionally amplify this risk. Adonisjs is a Node.js web framework that often interacts with databases through models or service classes, while DynamoDB is a NoSQL database that stores items as attribute-value maps. When developers build endpoints that query DynamoDB and serialize results directly to JSON, they may expose fields that should remain internal, such as administrative flags, internal identifiers, or sensitive user metadata.
In this stack, the vulnerability typically arises at the service or controller layer. An endpoint might perform a getItem or query on a DynamoDB table and return the full item without filtering out sensitive attributes. Because DynamoDB does not enforce field-level permissions at query time, the application must explicitly exclude unnecessary data. If the Adonisjs controller passes the raw DynamoDB record to the response layer, fields like password_hash, api_key, or role can be exposed to clients. This is especially dangerous when combined with broad IAM policies that allow read access to many attributes, as the API then becomes a direct channel for data exfiltration.
Real-world attack patterns include enumeration via over-fetching, where an attacker iterates through user IDs and collects sensitive attributes not intended for their role. For example, an endpoint like /api/users/:id might return the full DynamoDB item including isAdmin and refreshToken. If the response is not filtered, an authenticated user can read other users' administrative status or tokens, leading to privilege escalation or account compromise. This maps to the OWASP API Top 10 API1:2023 – Broken Object Level Authorization when combined with insufficient authorization checks, and can also violate compliance requirements such as GDPR minimization principles.
Another scenario involves logging or error handling that inadvertently echoes DynamoDB attribute values. If an Adonisjs service logs the full response object before sending it to the client, sensitive data can appear in application logs or be returned in error messages. The use of unauthenticated endpoints exacerbates this, as any external actor can trigger the logging path. Tools like middleBrick can detect these exposures by scanning the unauthenticated attack surface and identifying endpoints that return sensitive fields such as secrets or PII, providing prioritized findings with remediation guidance.
To mitigate, developers should adopt a strict field selection strategy and validate that only required attributes are serialized. Using middleBrick’s continuous monitoring in the Pro plan can help detect regressions by scanning on a configurable schedule and alerting when new sensitive fields appear in responses. The CLI tool allows quick checks from the terminal, while the GitHub Action can fail builds if a scan exceeds a defined risk threshold, integrating security into the development lifecycle without requiring internal infrastructure knowledge.
Dynamodb-Specific Remediation in Adonisjs
Remediation focuses on ensuring that only necessary, non-sensitive attributes are retrieved from DynamoDB and included in API responses. This involves filtering at the database query level and applying explicit transformation before serialization. Below are concrete code examples for Adonisjs that demonstrate secure patterns when working with DynamoDB.
First, define a service that queries DynamoDB and returns a sanitized object. Use the AWS SDK to perform the operation and explicitly pick required fields.
// services/UserService.js
const { DynamoDBClient, GetItemCommand } = require('@aws-sdk/client-dynamodb');
const { marshall, unmarshall } = require('@aws-sdk/util-dynamodb');
class UserService {
constructor() {
this.client = new DynamoDBClient({ region: 'us-east-1' });
}
async getUserPublicProfile(userId) {
const command = new GetItemCommand({
TableName: process.env.USERS_TABLE,
Key: marshall({ userId: { S: userId } }),
// Use ProjectionExpression to limit returned attributes
ProjectionExpression: 'userId, username, email, createdAt'
});
const response = await this.client.send(command);
if (!response.Item) return null;
// Unmarshall only the projected fields
return unmarshall(response.Item);
}
}
module.exports = new UserService();
In this example, ProjectionExpression ensures that only userId, username, email, and createdAt are retrieved from DynamoDB, preventing sensitive attributes from ever entering the response pipeline. The unmarshall step then converts the DynamoDB format back to plain JavaScript objects containing only those fields.
In an Adonisjs controller, use the service method and return the result directly:
// controllers/UserController.js
const UserService = use('App/Services/UserService');
class UserController {
async show({ params, response }) {
const user = await UserService.getUserPublicProfile(params.id);
if (!user) {
return response.status(404).json({ message: 'User not found' });
}
return response.json(user);
}
}
module.exports = UserController;
For list endpoints, apply the same principle. Use Scan or Query with ProjectionExpression and avoid returning raw DynamoDB metadata such as Attributes or ConsumedCapacity.
// services/UserService.js (continued)
async listUsersPublic() {
const command = new ScanCommand({
TableName: process.env.USERS_TABLE,
ProjectionExpression: 'userId, username, email, createdAt'
});
const response = await this.client.send(command);
return response.Items.map(item => unmarshall(item));
}
Additionally, enforce attribute-level access control within the service by checking the requesting user’s role before including optional fields. This complements the API’s authorization layer and reduces the impact of misconfigured IAM policies.
Finally, integrate middleBrick’s CLI or GitHub Action to validate that no sensitive fields are present in endpoint responses. The scanner can confirm that fields like password_hash or api_key are absent, providing actionable feedback during development and in CI/CD pipelines.
Related CWEs: propertyAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-915 | Mass Assignment | HIGH |