Summary:
A critical vulnerability, CVE-2025-24888, was discovered in the SecureDrop Client—a desktop application used in newsrooms for secure source communication. This flaw, fixed in version .14.1, allows a compromised SecureDrop Server to execute arbitrary code on a workstation by abusing filename handling in reply downloads. This article explains the vulnerability, exploitation steps, technical details with code snippets, and how it was patched.
What is SecureDrop Client?
SecureDrop is a widely-used tool by media organizations to facilitate confidential communications between journalists and sources. SecureDrop Client is a desktop companion app running inside a QubesOS virtual machine (sd-app). It connects to a physical SecureDrop Server, typically hardened and accessible only over Tor.
How the Vulnerability Works
Root Cause:
When a reply is downloaded from the SecureDrop Server, the client's code trusts the filename provided in the Content-Disposition HTTP header and writes the encrypted file to disk. This filename is chosen and sanitized server-side. If the SecureDrop Server is compromised, it can deliberately supply a malicious filename (such as one that writes to a sensitive location, or starts a program on user login).
After download, the client later checks the filename to prevent path traversal before moving the file into its storage directory. Too late—the file is already written, and if a path traversal occurred, it's left in the attacker's chosen spot.
Attacker gains access to SecureDrop Server (must already be compromised).
2. Attacker causes Server to send an encrypted reply with a Content-Disposition header containing a path-traversal filename (e.g., ../.config/autostart/evil.desktop).
3. SecureDrop Client downloads and writes the file to this location before checking for path traversal.
4. safe_move() function detects the path issue and prevents moving, but the malicious file remains where it was written.
Exploitation:
- By writing a .desktop file in /home/user/.config/autostart/, the attacker ensures their payload executes automatically when the user logs in—code execution achieved!
For illustration, here’s a simplified example of the affected logic
import os
def download_reply(response):
# Get filename from HTTP header, e.g., '../../../.config/autostart/evil.desktop'
filename = response.headers.get("Content-Disposition").split("filename=")[1]
filepath = os.path.join("/home/user/Downloads", filename)
# Write the file (danger: filename might contain path traversal)
with open(filepath, "wb") as f:
f.write(response.content)
# Later, check path for traversal before moving to storage directory
if not is_safe_path(filename):
print("Unsafe path detected! Not moving file.")
return
safe_move(filepath, "/some/data/directory")
Key problem:
The *write* happens before the safety check. At this point, any malicious filename from a compromised server is honored by the underlying OS.
Suppose a compromised SecureDrop Server sends this header
Content-Disposition: attachment; filename="../../../.config/autostart/evil.desktop"
And the body contains a .desktop file to launch a payload. When the workstation user logs in, the payload runs automatically.
The fix: Validate and sanitize the filename before writing to disk.
def download_reply(response):
filename = extract_filename_safely(response.headers)
if not is_safe_path(filename):
raise Exception("Invalid filename!")
filepath = os.path.join("/home/user/Downloads", filename)
# Now safe to write
with open(filepath, "wb") as f:
f.write(response.content)
References & Further Reading
- SecureDrop Security Advisory (GitHub)
- SecureDrop Official
- OWASP File Upload Security Cheat Sheet
- Autostart Specification
Vulnerability reported privately.
- Patch released (see release notes).
Users urged to upgrade SecureDrop Client to ≥ .14.1 as soon as possible.
Takeaway:
This flaw highlights the importance of validating any input from even “trusted” environments—especially where environments interact across trust boundaries. Filename handling mistakes are easy to make, and in tightly secured workflows like SecureDrop’s, attacks are often only possible after other layers are already breached. Defense in depth is key!
*This article is exclusive to this platform. For future updates, monitor the SecureDrop Client GitHub.*
Timeline
Published on: 02/13/2025 18:18:23 UTC