Command Injection in Hapi with Dynamodb
Command Injection in Hapi with Dynamodb — how this specific combination creates or exposes the vulnerability
Command injection occurs when untrusted input is concatenated into system or shell commands. In a Hapi application that interacts with DynamoDB, the risk typically arises not from DynamoDB itself, but from how data retrieved from or sent to DynamoDB is passed to underlying host utilities. For example, if your Hapi route reads an item from DynamoDB containing a filename or path, and then uses that value in a child process execution (e.g., via Node.js child_process methods), an attacker who can influence the DynamoDB content may inject shell metacharacters.
Consider a scenario where an endpoint retrieves a user-supplied key from DynamoDB and uses it in a system command to generate a report. If the key includes characters like ;, &, or backticks, and the code does not sanitize or escape them, the command may execute unintended operations. This is a classic command injection vector amplified by DynamoDB as the data store. Even though DynamoDB does not execute shell commands, the application logic that combines DynamoDB data with shell execution becomes the weak link.
Another angle involves environment variables or configuration values stored in DynamoDB that are later used to construct command-line arguments for external tools. If these values are not validated, an attacker who can write to DynamoDB (for instance, via an IDOR or overly permissive IAM policy) can set malicious payloads that the Hapi service will later execute. This is especially dangerous when the Hapi service runs with elevated privileges or in a shared environment.
In the context of middleBrick’s checks, such patterns are flagged under BFLA/Privilege Escalation and Unsafe Consumption categories, because the unsafe linkage between data storage and command execution can lead to arbitrary command execution. The scanner does not rely on internal architecture but observes the effective attack surface: unauthenticated or low-privilege input that reaches a command interpreter via DynamoDB-influenced data paths.
Dynamodb-Specific Remediation in Hapi — concrete code fixes
To mitigate command injection in Hapi when using DynamoDB, ensure that any data retrieved from or stored in DynamoDB is never directly interpolated into shell commands. Use structured APIs for external processes, and validate and sanitize all inputs and stored values. Below are concrete remediation steps with code examples.
1. Avoid Shell Interpolation Entirely
Use Node.js child process methods that do not invoke a shell by default. Prefer spawn with an argument array, and avoid exec when dealing with DynamoDB-derived strings.
const { spawn } = require('child_process');
const dynamoDb = new AWS.DynamoDB.DocumentClient();
const handler = async (request, h) =>
{
const { tableName, userKey } = request.query;
// Retrieve item from DynamoDB
const data = await dynamoDb.get({
TableName: tableName,
Key: { id: userKey }
}).promise();
const item = data.Item;
if (!item) {
return h.response({ error: 'Not found' }).code(404);
}
// Safe: use spawn with arguments, no shell involvement
const child = spawn('python', ['/path/script.py', item.safeParam]);
let stdout = '';
child.stdout.on('data', (chunk) => { stdout += chunk; });
return new Promise((resolve, reject) => {
child.on('close', (code) => {
if (code !== 0) return reject(new Error('Script failed'));
resolve(h.response({ output: stdout }));
});
});
};
2. Validate and Restrict Data from DynamoDB
If the DynamoDB item contains values that must be used in shell contexts, enforce strict allowlists and escape dangerous characters. Never trust data simply because it came from a NoSQL database.
const escapeShellArg = (arg) =
> {
if (typeof arg !== 'string') return arg;
// Allow only alphanumeric, dashes, underscores, and dots
if (!/^[a-zA-Z0-9_.-]+$/.test(arg)) {
throw new Error('Invalid argument: contains unsafe characters');
}
return arg;
};
const handler = async (request, h) =
>
{
const { tableName, fileId } = request.query;
const data = await dynamoDb.get({
TableName: tableName,
Key: { file_id: fileId }
}).promise();
const safeFileId = escapeShellArg(data.Item.file_id);
// Now safe to use in a controlled command context
const child = spawn('convert', ['-resize', '100x100', `${safeFileId}.png`, `${safeFileId}_small.png`]);
// handle output as above
};
3. Secure DynamoDB Write Paths
Prevent storage of malicious payloads by validating data before it enters DynamoDB. This reduces the blast radius in case downstream processes consume these values.
const validateAndPutItem = async (tableName, candidate) =
>
{
if (!candidate || typeof candidate.metadata !== 'string') {
throw new Error('Invalid metadata');
}
// Allow only safe characters in metadata that might be used externally
if (!/^[\w\-\s]+$/.test(candidate.metadata)) {
throw new Error('Metadata contains disallowed characters');
}
await dynamoDb.put({
TableName: tableName,
Item: {
id: candidate.id,
metadata: candidate.metadata
}
}).promise();
};
4. Use Middleware for Input Normalization
In Hapi, leverage route validation and preprocessing to sanitize inputs before they reach DynamoDB or any external command.
const Hapi = require('@hapi/hapi');
const safeParam = (value, helpers) =
=>
{
const sanitized = value.replace(/[^a-zA-Z0-9_-]/g, '');
return { value: sanitized };
};
const server = Hapi.server({ port: 4000 });
server.route({
method: 'GET',
path: '/process/{fileId}',
options: {
validate: {
params: {
fileId: safeParam
}
},
handler: async (request, h) =
=>
{
const { fileId } = request.params;
// Use fileId safely with DynamoDB and process execution
}
}
});
5. Least Privilege and Environment Controls
Ensure the process executing commands derived from DynamoDB runs with minimal permissions. Avoid environment variables that can be poisoned via DynamoDB writes. Use IAM policies to limit write access to DynamoDB items that influence external commands.
These patterns align with middleBrick’s checks for BFLA/Privilege Escalation and Unsafe Consumption. By combining DynamoDB data handling discipline with strict command construction, you reduce the attack surface without relying on internal scanning mechanics.
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 |