Listen to this Post
Intro – How CVE-2026-34084 Works
The vulnerability exists in PhpSpreadsheet’s `File::prohibitWrappers()` helper, which was designed to block stream wrappers like phar://, php://, `data://` or `expect://` in file paths. The original patch uses `parse_url($filename, PHP_URL_SCHEME)` and then checks is_string($scheme) && strlen($scheme) > 1. For a standard wrapper path like phar://x/dummy.csv, `parse_url` returns the string "phar", the condition fires, and an exception is thrown – this works correctly.
However, when an attacker supplies a path with three or more slashes after the scheme, for example phar:///work/exploit.phar/dummy.csv, the behavior of `parse_url` changes. In this case `parse_url` returns boolean `false` instead of a scheme string. Because `false` is not a string, the `is_string()` check fails, the `strlen` branch is never entered, and the function returns without throwing any exception.
The caller (e.g. IOFactory::load($attackerPath)) then proceeds with the path. PHP’s internal stream layer still interprets `phar:///…` as a valid phar wrapper and opens the underlying `.phar` file. On PHP 7.x, simply calling `is_file()` or any file operation on a phar wrapper triggers automatic deserialization of the phar’s metadata. This deserialization invokes magic methods like `__wakeup()` and `__destruct()` of attacker-controlled objects, leading directly to Remote Code Execution (RCE).
On PHP 8.x, automatic metadata deserialization for plain file operations was removed. Therefore the bypass only gives a file-read primitive via the phar wrapper. RCE would only re-appear if downstream code explicitly calls `Phar::getMetadata()` – which PhpSpreadsheet does not do. Nevertheless, the bypass itself is present in all tested versions up to the latest 5.7.0 tag. The vulnerable source code is byte-identical across all six affected tags. The attack requires only the ability to control the filename passed to IOFactory::load().
DailyCVE Form:
Platform: PhpSpreadsheet
Version: 1.30.4-5.7.0
Vulnerability: Phar wrapper bypass
Severity: Critical (PHP7)
date: 2026-05-03
Prediction: 2026-06-15
What Undercode Say:
Analytics – reproduction commands and evidence
Full reproduction using Docker (no local PHP) git clone <victim-repo> cd test docker run --rm -v $(pwd):/work -w /work php:7.4-cli php build-phar.php docker run --rm -v $(pwd):/work -w /work composer:2 composer require phpoffice/phpspreadsheet:5.7.0 docker run --rm -v $(pwd):/work -w /work php:8.3-cli php exploit.php | tee evidence.txt Negative control (should throw exception) php exploit.php phar://x/dummy.csv Positive control (bypass) php exploit.php phar:///work/exploit.phar/dummy.csv On PHP 7.4, marker file confirms RCE cat pwned_marker Output: WAKEUP: phpspreadsheet-bypass DESTRUCT: phpspreadsheet-bypass
How Exploit:
- Build a malicious `exploit.phar` with `phar.readonly=0` containing a gadget object in metadata.
2. Supply path `phar:///work/exploit.phar/dummy.csv` to `IOFactory::load()`.
3. `prohibitWrappers()` returns early because `parse_url` returns `false` for triple‑slash variant.
4. PHP opens the phar wrapper, deserializes metadata (PHP 7.x) → RCE.
5. On PHP 8.x only file read is possible unless `Phar::getMetadata()` is called elsewhere.
Protection:
Apply the following fix in `vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/File.php`:
public static function prohibitWrappers(string $filename): void
{
// Safe detection – independent of slash count
if (str_contains($filename, '://')) {
throw new Exception("Stream wrappers are not permitted as file paths: {$filename}");
}
}
Alternative: use `realpath($filename) === false` to reject wrapper paths.
Update to a patched version once released (expected June 2026).
If patching not possible, sanitize all user‑supplied filenames to reject any string containing ://.
Impact:
- PHP 7.x (e.g. branch 1.30.4) – Full Remote Code Execution. Attacker can run arbitrary PHP code, write files, or compromise the server.
- PHP 8.x (branches 2.1.x to 5.7.x) – Limited to arbitrary file read via phar wrapper (if an attacker can control the path and a valid phar file is uploaded). No direct RCE in core PhpSpreadsheet, but information disclosure may lead to further attacks.
- Scope – Any application using PhpSpreadsheet that loads spreadsheets from user‑controlled filenames is vulnerable. The attack requires no authentication if the filename parameter is exposed.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

