Zip Slip in Adonisjs with Api Keys
Zip Slip in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when an archive (for example, a ZIP file) contains entries with malicious paths such as ../../../etc/passwd. If an AdonisJS application extracts user-supplied archives without validating and sanitizing member paths, an attacker can traverse outside the intended extraction directory. When the application also uses API keys for authentication or rate limiting, the presence of these keys in request headers or logs can correlate malicious uploads to specific keys, making abuse attribution possible and exposing key‑based access controls to misuse.
In AdonisJS, a typical file upload handler might accept an uploaded archive and extract it with a library such as adm-zip or yauzl. If the handler trusts filenames from the archive, an attacker can include paths like ../../malicious.js. During extraction, these paths can overwrite arbitrary files on the server, including application code or configuration files that contain references to how API keys are validated. This can lead to privilege escalation or unauthorized access when the compromised code or configuration mishandles API keys.
Moreover, API keys often appear in HTTP headers (e.g., X-API-Key) and in application logs. If an attacker manages to upload and execute a malicious archive that modifies routing or authentication logic, they can capture or manipulate API key usage. For example, they might alter middleware behavior to bypass key validation or exfiltrate keys via crafted responses. The combination of Zip Slip extraction logic and API key handling thus expands the attack surface: the vulnerability is not only about file system write capabilities, but also about how compromised endpoints can affect key management and exposure.
Consider an endpoint that processes an uploaded ZIP and later uses environment-based API key checks. A malicious archive containing a file like ./startup/config.js could overwrite configuration that determines whether API key checks are enforced. If the overwrite disables key validation, the attacker gains access without a valid key. Even without overwriting source, an insecure extraction that places files in a publicly accessible directory can allow an attacker to serve files that leak keys embedded in client‑side code or logs.
To detect this risk, security scanners perform unauthenticated black‑box checks that submit archives with traversing paths and inspect whether the server resolves them safely outside the target directory. They also review whether API key handling logic remains intact after extraction and whether logs or error messages inadvertently expose keys. MiddleBrick’s checks include input validation and data exposure tests that highlight these interactions, helping identify whether an AdonisJS endpoint vulnerable to Zip Slip also exposes API key–related weaknesses.
Api Keys-Specific Remediation in Adonisjs — concrete code fixes
Remediation focuses on two areas: safely handling ZIP archives and ensuring API key validation remains robust even if application code or configuration is tampered with.
Secure archive extraction in AdonisJS
Always sanitize archive member paths before extraction. For adm-zip, iterate entries and resolve each path to ensure it stays within the intended directory. Below is a secure extraction example in an AdonisJS controller:
import { join, resolve } from 'path';
import { ensureDir } from 'fs-extra';
import { tmpdir } from 'os';
import { randomBytes } from 'crypto';
import AdmZip from 'adm-zip';
export default class FileController {
public async uploadZip() {
const tmpDir = join(tmpdir(), `upload-${randomBytes(8).toString('hex')}`);
await ensureDir(tmpDir);
const zipBuffer = this.request.file('zip', { types: ['file'] }).tmpPath;
const zip = new AdmZip(zipBuffer);
const zipEntries = zip.getEntries();
const base = resolve(tmpDir);
for (const entry of zipEntries) {
const target = resolve(base, entry.entryName);
if (!target.startsWith(base)) {
throw new Error('Invalid zip entry: path traversal detected');
}
await zip.extractEntryTo(entry, base, false, true);
}
// Process extracted files safely
}
}
This code creates a unique temporary directory, validates each entry’s resolved path, and throws an error if a path escapes the base directory. It avoids symbolic link risks by not preserving directory structures blindly and uses resolve to normalize paths.
Protect API key handling
Keep API key validation in a dedicated, isolated layer (such as an HTTP middleware) that does not depend on files extracted from user input. Store keys in environment variables and avoid writing key‑related configuration to locations an attacker could overwrite. Example middleware that checks X-API-Key:
import { Exception } from '@adonisjs/core/build/standalone';
export default class ApiKeyMiddleware {
public async handle(ctx, next) {
const providedKey = ctx.request.header('x-api-key');
const validKey = process.env.API_KEY;
if (!providedKey || providedKey !== validKey) {
throw new Exception('Unauthorized', 401, 'INVALID_API_KEY');
}
await next();
}
}
Register this middleware in start/kernel.ts and apply it to routes that require key authentication. This ensures validation remains consistent and is not influenced by uploaded archives or modified configuration files.
Operational practices
- Do not extract archives to web‑accessible directories.
- Use strict allowlists for file extensions and paths.
- Rotate API keys if you suspect exposure, and avoid logging raw keys.
- Scan uploads and dependencies regularly; MiddleBrick’s dashboard and CLI can be integrated into your workflow to continuously monitor risk without credentials.