The vulnerability is a classic Zip Slip issue within the unzipDirectory function in packages/api/src/shell/unzipDirectory.js. This function is responsible for extracting files from a ZIP archive. The core of the vulnerability lies in the fact that it concatenates a base directory with a filename taken from the ZIP archive without sanitizing or validating the filename. An attacker can craft a ZIP file with entries containing path traversal sequences (e.g., ../../../etc/hosts). When unzipDirectory processes this entry, it constructs a path that points outside the intended extraction directory, leading to an arbitrary file write on the filesystem.
The exploit is triggered via the /api/archive/unzip endpoint, which is handled by the unzip function in packages/api/src/controllers/archive.js. This function takes the name of the ZIP file to be extracted directly from the user request and passes it to unzipDirectory without validation. The provided proof-of-concept demonstrates this by first uploading a malicious ZIP and then calling the unzip endpoint to trigger the file write.
The patch addresses the vulnerability in two main ways. First, it adds robust validation within unzipDirectory to resolve the absolute path of each extracted file and ensures it remains within the boundaries of the intended output directory. Second, it introduces a new validation function, assertSafeArchiveName, in packages/api/src/controllers/archive.js and applies it to all API endpoints that handle file or folder names, including unzip and saveUploadedZip, to prevent path traversal attacks at the controller level.