CVE-2026-84374 Overview
CVE-2026-84374 is a path traversal vulnerability [CWE-22] in Laravel Excel, a package that provides Excel exports and imports for Laravel applications. The flaw affects versions from 3.1.8 up to but not including 3.1.70. The Maatwebsite\Excel\Files\Disk::copy() method resolves caller-controlled destination paths against the process working directory using realpath() instead of the configured Flysystem disk. Attackers who control export path input can overwrite arbitrary writable files on the host. Overwriting an executable PHP file can escalate to remote code execution.
Critical Impact
Applications passing user-influenced paths to Excel::store(), $export->store(), or storeExcel() can be coerced into overwriting arbitrary files, including PHP scripts, resulting in remote code execution.
Affected Products
- Laravel Excel (Maatwebsite/Laravel-Excel) versions 3.1.8 through 3.1.69
- Laravel applications using Excel::store(), $export->store(), or storeExcel() with caller-controlled paths
- Fixed in Laravel Excel 3.1.70
Discovery Timeline
- 2026-09-01 - CVE-2026-84374 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-84374
Vulnerability Analysis
The vulnerability resides in src/Files/Disk.php within the Maatwebsite\Excel\Files\Disk::copy() method. Instead of routing writes through the configured Flysystem disk, the method checks the destination with realpath() against the PHP process working directory. When the resolved path names an existing writable file, the code opens it with fopen() in rb+ mode and calls stream_copy_to_stream() to write export content directly. This path bypasses Flysystem's path confinement and safety checks.
The rb+ mode does not truncate the target file. If the new export content is shorter than the original file, trailing bytes from the original file remain intact, producing a partial overwrite. Applications that pass request-derived filenames or path segments to the export APIs expose the host filesystem to modification.
Root Cause
The root cause is improper limitation of a pathname to a restricted directory [CWE-22]. The Disk::copy() implementation uses realpath() for existence checks rather than delegating file placement to the Flysystem adapter, which enforces disk root confinement. Trusting caller-supplied destination strings without validating that they resolve within the configured disk root permits directory traversal outside the intended storage location.
Attack Vector
An attacker supplies application input that influences the destination path passed to Excel::store($export, $path), $export->store($path), or storeExcel($path). Relative traversal sequences allow the resolved path to point at any writable file readable by the PHP process, including deployed PHP source files. When the export runs, the target file is opened in rb+ mode and overwritten with the Excel export content. If the target is a PHP file executed by the web server, the attacker gains remote code execution on the next request that includes it.
// Vulnerable code path in src/Files/Disk.php (pre-3.1.70)
if (realpath($destination)) {
$tempStream = fopen($destination, 'rb+');
$success = stream_copy_to_stream($readStream, $tempStream) !== false;
if (is_resource($tempStream)) {
fclose($tempStream);
}
} else {
$success = $this->put($destination, $readStream);
}
// Patched code in 3.1.70 - always delegates to Flysystem
$success = $this->put($destination, $readStream);
Source: GitHub Commit b5cafdf
Detection Methods for CVE-2026-84374
Indicators of Compromise
- Unexpected modification timestamps on PHP files inside application directories such as public/, app/, or vendor/
- PHP files whose contents begin with the ZIP local file header signature PK\\x03\\x04 (XLSX output written over source)
- PHP source files with unexpected trailing bytes after valid PHP code, indicating a non-truncating overwrite
- Web server logs showing export endpoints receiving requests with ../ sequences or absolute paths in filename parameters
Detection Strategies
- Inventory all call sites of Excel::store(), $export->store(), and storeExcel() and inspect whether the path argument derives from HTTP input
- Static analysis rules that flag concatenation of request variables into Laravel Excel storage paths
- File integrity monitoring on Laravel application roots to catch unexpected changes to .php files
Monitoring Recommendations
- Alert on writes to files under the web root that do not originate from the deployment pipeline
- Monitor PHP-FPM and web server access logs for export routes invoked with suspicious path parameters
- Track process file descriptor activity for fopen() calls to non-storage directories from PHP workers
How to Mitigate CVE-2026-84374
Immediate Actions Required
- Upgrade the maatwebsite/excel package to version 3.1.70 or later using composer update maatwebsite/excel
- Audit all export code paths and remove user input from destination path arguments
- Rotate application secrets and review PHP files for tampering if the vulnerable version handled untrusted input
Patch Information
The fix is available in Laravel Excel 3.1.70. The patch removes the realpath() branch in Disk::copy() and routes all writes through $this->put() so that Flysystem enforces disk root confinement. Details are documented in GHSA-c7r6-vx3h-w5g2.
Workarounds
- Constrain the destination path to a whitelisted directory and validate against traversal sequences before calling export APIs
- Use basename() on any user-supplied filename component and prepend a fixed application-controlled directory
- Set filesystem permissions so the PHP process cannot write to directories containing executable PHP source
# Upgrade Laravel Excel to the patched version
composer require maatwebsite/excel:^3.1.70
# Verify installed version
composer show maatwebsite/excel | grep versions
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.