Zip Slip in Adonisjs with Dynamodb
Zip Slip in Adonisjs with Dynamodb — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when user-controlled archive entries are extracted without proper validation, allowing files to be written outside the intended directory. In an AdonisJS application that interacts with Amazon DynamoDB, this risk arises when the server processes uploaded archives (e.g., for bulk imports or backups) and uses metadata from those archives to construct file paths before persisting records to DynamoDB.
Consider an endpoint that accepts a ZIP file, extracts it, and stores file metadata such as name and size in a DynamoDB table. If the extraction logic does not sanitize path segments like ../, an attacker can craft an archive containing entries such as ../../../etc/passwd. During extraction, these entries traverse outside the extraction root, potentially overwriting system or application files. Even if the application subsequently stores only the sanitized filename in DynamoDB, the damage may already be done — sensitive files could be overwritten or configuration files modified, leading to privilege escalation or service disruption.
The exposure is compounded because AdonisJS often uses structured data models that map directly to DynamoDB items. For example, a developer might map a file entry’s path field directly to a DynamoDB attribute without validating that the resolved path remains within the allowed directory. Because DynamoDB does not enforce filesystem semantics, the database record alone cannot prevent unsafe file operations. Thus, the vulnerability exists at the intersection of improper archive handling in AdonisJS and the assumption that DynamoDB-stored paths reflect safe, constrained locations.
An attacker does not need to exploit a runtime system command or injection flaw; they simply leverage path traversal during file extraction. After the malicious extraction, any subsequent operation that uses the stored path — such as reading configuration or serving files — may inadvertently reference unintended locations. Because the DynamoDB record appears valid, the application may trust it implicitly, creating a persistent security gap.
Dynamodb-Specific Remediation in Adonisjs — concrete code fixes
To mitigate Zip Slip in AdonisJS when using DynamoDB, you must validate and sanitize file paths before writing to the filesystem and before storing metadata in DynamoDB. The following approach combines secure extraction logic with safe DynamoDB item construction.
First, use a robust extraction library that prevents path traversal. For example, with the adm-zip package, validate each entry’s target path:
const AdmZip = require('adm-zip');
const path = require('path');
function safeExtractZip(buffer, destination) {
const zip = new AdmZip(buffer);
const zipEntries = zip.getEntries();
for (const entry of zipEntries) {
const targetPath = path.resolve(destination, entry.entryName);
if (!targetPath.startsWith(path.resolve(destination))) {
throw new Error('Invalid path detected: ' + entry.entryName);
}
zip.extractEntryTo(entry, destination, false, true);
}
}
Next, when storing file metadata in DynamoDB, ensure the path attribute is normalized and constrained. Use AdonisJS model hooks to sanitize data before persistence:
const { DateTime } = require('luxon');
const { v4: uuidv4 } = require('uuid');
const { DynamoDBDocumentClient, PutCommand } = require('@aws-sdk/lib-dynamodb');
const { ddbDocClient } = require('../../../providers/dynamodb_provider');
class FileMetadata {
constructor() {}
async create(entry) {
const safePath = path.normalize(entry.path).replace(/^(\/|)\\.\.(\/.)*$/, '');
const params = {
TableName: process.env.DYNAMODB_TABLE,
Item: {
id: uuidv4(),
name: entry.name,
path: safePath,
size: entry.size,
createdAt: DateTime.local().toISO(),
},
};
const command = new PutCommand(params);
await ddbDocClient.send(command);
return params.Item;
}
}
module.exports = FileMetadata;
Additionally, configure AdonisJS to restrict upload and extraction directories explicitly, and avoid using user-supplied paths directly when generating pre-signed URLs for DynamoDB-stored objects. Combine these measures with input validation rules in your route definitions to reject archives containing suspicious entries before processing.
Frequently Asked Questions
Why is DynamoDB insufficient to prevent Zip Slip on its own?
../../../etc/passwd; prevention must happen in application logic before data is written to DynamoDB or the filesystem.