PhpSpreadsheet, Phar Wrapper Bypass, CVE-2026-34084 (Critical) -DC-Jun2026-303

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:

  1. 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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top