CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

GHSA-xphh-5v4r-r3rx
CVSS 8.1|EPSS 0.08%

PsiTransfer Zip Slip: When 'Download All' Becomes 'Hack All'

Alon Barad
Alon Barad
Software Engineer•December 30, 2025•5 min read
PoC AvailableNot in KEV

Executive Summary (TL;DR)

PsiTransfer trusted user-supplied filenames a little too much. Attackers can upload files named like `../../.ssh/authorized_keys`. When a victim downloads these files as a ZIP or TAR, the server dutifully packs that malicious path. If the victim extracts this archive, the attacker's file escapes the download folder and overwrites critical system files, potentially leading to RCE on the client machine.

A critical Path Traversal vulnerability in PsiTransfer allows attackers to weaponize the 'Download Archive' feature. By uploading files with malicious filenames, attackers can generate archives that perform arbitrary file overwrites on the victim's machine upon extraction.

The Hook: Trust Issues in File Sharing

PsiTransfer is one of those delightful open-source tools that does exactly what it says on the tin: it lets you share files. No accounts, no complex cloud storage buckets, just a simple web interface to upload a file and get a link. It’s self-hosted, which implies a circle of trust. You trust the server, and the server trusts you. And therein lies the tragedy.

In the world of web security, trust is a four-letter word. PsiTransfer was designed to handle file uploads securely regarding storage. It renames uploaded files on the disk to unique IDs (SIDs) so that you can't accidentally upload a PHP shell and execute it on the server. Good job, developers. Secure design 101.

However, they forgot one crucial aspect: Metadata. When you upload a file, you aren't just sending bytes; you're sending a filename. PsiTransfer stored this filename in a database (JSONDB) to display it nicely to the next user. But what happens when that filename isn't just a name, but a roadmap to the victim's filesystem?

The Flaw: The 'Reflected' Zip Slip

Most security researchers are familiar with the classic 'Zip Slip' vulnerability. Usually, that involves an application extracting a malicious ZIP and getting owned because it writes files outside the target directory. This vulnerability is the inverse: it is the creation of a malicious ZIP.

Here is the logic flow that doomed the application:

  1. Ingestion: The attacker uploads a file. The HTTP POST request includes metadata. The attacker intercepts this and changes the filename to ../../../../Users/Admin/.ssh/authorized_keys.
  2. Storage: PsiTransfer saves the file content safely as files/12345.dat, but saves the name in the database exactly as provided: ../../../../Users/Admin/.ssh/authorized_keys.
  3. Weaponization: The unsuspecting victim navigates to the download page and clicks "Download all as ZIP".

At this moment, the server dynamically generates an archive. It reads the safe content 12345.dat, but it labels the entry in the ZIP header using the stored malicious name. The server effectively constructs a weaponized archive on the fly and hands it to the victim. It is a Reflected File Download attack powered by Path Traversal.

The Code: Anatomy of a Path Traversal

The vulnerability lived in the way PsiTransfer handled the archiver and tar-stream libraries. It took the input directly from the metadata store without sanitization. Let's look at the logic before the patch.

In the vulnerable version, the code looked something like this (pseudocode based on the logic):

// Vulnerable Logic
archive.append(fileStream, { name: file.metadata.name });

If file.metadata.name contains ../, the archiver library (compliant with the ZIP spec) writes those characters into the file header. The fix involved introducing a strict sanitizer. The patch was applied in commit 6c71bc0b8afa1ffa7aabd6c5fb28677651fd57b6.

Here is the remediation logic introduced in lib/utils.js:

const path = require('path');
 
module.exports.toSafeBasename = (str) => {
  // 1. Remove control characters
  str = str.replace(/[\x00-\x1f\x80-\x9f]/g, '');
  // 2. Force basename (strips directory components)
  str = path.posix.basename(str);
  // 3. Fallback for empty strings or prohibited names
  if (!str || str === '.' || str === '..') {
    return 'renamed-by-system';
  }
  return str;
};

This function is a sledgehammer. It uses path.posix.basename() which aggressively strips everything except the final file name. ../../etc/passwd becomes passwd. Simple, effective, and brutal.

The Exploit: Dropping the Payload

Let's walk through a practical attack scenario. We aren't targeting the server here; we are using the server as a mule to target other users (perhaps an admin downloading logs or backup files).

Step 1: The Setup

The attacker prepares a legitimate-looking file (e.g., quarterly_report.pdf) but intercepts the upload request using Burp Suite or a simple Python script.

Step 2: The Injection

The attacker modifies the JSON payload in the upload request:

{
  "metadata": {
    "name": "../../../../../../home/victim/.bashrc",
    "mime": "application/pdf"
  }
}

PsiTransfer accepts this with a smile (HTTP 200 OK).

Step 3: The Trap

The attacker sends the download link to the victim: "Hey, I uploaded the logs you asked for, just hit 'Download as TAR' to get them all at once."

Step 4: Execution

The victim downloads archive.tar.gz. They open a terminal and run tar -xzvf archive.tar.gz.

Because standard tar (and many GUI tools) preserves paths by default or if flags are misused, the file extracts outside the current directory, overwriting the victim's .bashrc. The next time the victim opens a terminal... BOOM. The attacker's code executes.

The Fix: Better Late Than Never

The remediation is straightforward but highlights the importance of 'Defense in Depth'. The developers released version 2.3.1, which implements the sanitization logic described above.

[!TIP] For Developers: Never trust a filename. It is user input just like a SQL query or HTML body. Always generate your own filenames internally, or strip the input down to alphanumeric characters only.

If you are running a version of PsiTransfer older than 2.3.1, you are essentially hosting a malware distribution platform for anyone who can access your upload endpoint. Update immediately.

If you cannot update, your only defense is to disable public uploads or force users to download files one by one (avoiding the archive generation logic), though even single-file downloads can be risky if the Content-Disposition header is mishandled by the browser.

Official Patches

GitHubCommit 6c71bc0 - Implement filename sanitization

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
EPSS Probability
0.08%
Top 100% most exploited
1,500
Estimated exposed hosts via Shodan

Affected Systems

PsiTransfer < 2.3.1

Affected Versions Detail

ProductAffected VersionsFixed Version
PsiTransfer
psi-4ward
< 2.3.12.3.1
AttributeDetail
Bug ClassPath Traversal / Zip Slip
Attack VectorNetwork (Uploaded Metadata)
CVSS8.1 (High)
ImpactClient-Side Arbitrary File Write
ComponentArchive Generator (lib/endpoints.js)
Exploit StatusFunctional PoC Available

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1566Phishing
Initial Access
T1204.002User Execution: Malicious File
Execution
T1553Subvert Trust Controls
Defense Evasion
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The application allows user input to control paths used in filesystem operations, specifically within archive generation, allowing traversal outside the intended directory.

Exploit Resources

Known Exploits & Detection

GitHubSecurity advisory containing reproduction steps

Vulnerability Timeline

Vulnerability Timeline

Patch Committed (v2.3.1)
2024-05-24
Advisory Published
2024-05-27

References & Sources

  • [1]GHSA-xphh-5v4r-r3rx Advisory
  • [2]GitLab Advisory

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.