Kritisch

PHPSpreadsheet has a patch bypass for CVE-2026-34084

  • Veröffentlicht: 08.06.2026
  • Aktualisiert: 11.10.2026 10:22

Summary

CVE-2026-34084 was patched by the helper File::prohibitWrappers. The helper calls parse_url($filename, PHP_URL_SCHEME) and then checks is_string($scheme) && strlen($scheme) > 1 to reject stream wrappers such as phar://, php://, data:// or expect://. The check is not equivalent to "does the path contain a wrapper". When the input has the form phar:///path/file.phar/inner with three or more slashes after the scheme, parse_url returns boolean false instead of returning the scheme string. The is_string($scheme) branch is therefore skipped, the helper returns without throwing, and the caller proceeds. PHP's stream layer, however, still treats phar:///... as a valid phar wrapper and opens the underlying phar file. The result is that IOFactory::load($attackerPath) walks past the patch and still touches the phar wrapper. On PHP 7.x, simply reaching the phar wrapper via is_file is enough for PHP to automatically deserialize the phar metadata, which in turn invokes the magic methods __wakeup and __destruct of an attacker controlled object and gives full RCE. On PHP 8.x, automatic metadata deserialization for plain file ops was removed, so the chain at the PhpSpreadsheet layer reduces to a phar wrapper file read primitive, and RCE only resurfaces if the downstream consumer ever calls Phar::getMetadata.

Vulnerable code

The file vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/File.php is byte identical across all six latest tags listed below:

php
public static function prohibitWrappers(string $filename): void
{
    $scheme = parse_url($filename, PHP_URL_SCHEME);
    if (is_string($scheme) && strlen($scheme) > 1) {
        throw new Exception("Stream wrappers are not permitted as file paths: {$filename}");
    }
}

For input phar://x/dummy.csv the call returns the string "phar" and the throw fires correctly. For input phar:///work/exploit.phar/dummy.csv the same call returns false and the throw is skipped, which is the bypass.

Confirmed affected versions

Tested on 2026-05-03. The prohibitWrappers source on disk is identical across all six tags.

Branch Latest tag PHP under test Result
1.x 1.30.4 7.4 bypass plus full RCE, gadget wrote marker file
2.1.x 2.1.16 8.3 bypass
2.4.x 2.4.5 8.3 bypass
3.10.x 3.10.5 8.3 bypass
5.6.x 5.6.0 8.3 bypass
5.7.x 5.7.0 8.3 bypass

Version 1.30.4 is the latest tag of the 1.x branch, which is the only branch that still supports PHP 7.x. Version 5.7.0 is the latest tag overall on Packagist at the time of testing.

No branch beyond 1.30.x allows any release before Php 8. For branches beyond 1.30.x, although the code identified above is in error, and will be corrected, it does not lead to any security exposure. That would require a Phar::getMetadata call, which is not present in PhpSpreadsheet. If possible and reasonable, the release notes for the fix on the other branches will include release-note: security.

Reproduction

Requires Docker only, no local PHP install. Run:

bash
bash run.sh

The script does the following in order: build exploit.phar using php:7.4-cli with phar.readonly=0, install phpoffice/phpspreadsheet:5.7.0 through composer and run exploit.php on php:8.3-cli to show that the bypass still works against the latest tag, then install 1.30.4 and run again on php:7.4-cli to show the full RCE chain. All output is teed to evidence.txt.

exploit.php ships two controls. The negative control uses phar://x/dummy.csv to confirm that the patch still rejects the standard wrapper form. The positive control uses phar:///work/exploit.phar/dummy.csv to show that the three slash variant slips through. On PHP 7.4 the gadget writes the file pwned_marker containing the lines WAKEUP: phpspreadsheet-bypass and DESTRUCT: phpspreadsheet-bypass, which is the proof that attacker controlled code ran inside the victim process.

Suggested fix

Do not rely on parse_url to detect wrappers, because its behavior depends on the slash count and on the PHP version. Either of these is safe:

php
public static function prohibitWrappers(string $filename): void
{
    if (str_contains($filename, '://')) {
        throw new Exception("Stream wrappers are not permitted as file paths: {$filename}");
    }
}

Alternatively, run the path through realpath() first, since realpath returns false for any wrapper prefixed path.

Files in this report

  • build-phar.php: builds exploit.phar with a gadget object in its metadata.
  • exploit.php: main PoC, with the negative and positive controls.
  • exploit.phar: prebuilt phar, the gadget writes a marker when deserialized.
  • composer.json: spec used by composer to install the version under test.
  • run.sh: end to end reproducer through Docker.
  • evidence.txt: log captured from the most recent run.sh invocation.

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
Composer-Paket phpoffice/phpspreadsheet < 1.30.5 1.30.5

Verweise

CVSS-Wert -
CVSS-Vektor
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Schwäche (CWE)
CWE-502
Plattform
Composer
Paket
phpoffice/phpspreadsheet
Veröffentlicht
08.06.2026
Aktualisiert
11.10.2026 10:22

Quellen und Lizenzen

OSV / GitHub Advisory Database - GHSA-87m4-826x-3crx - CC BY 4.0

Schwachstellenhistorie: phpoffice/phpspreadsheet

Alle veröffentlichten Schwachstellen dieses Pakets (Composer-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (31) im Archiv
Einträge insgesamt
31
Erste → letzte
11.2019 07.2026
Ohne Fix
0
In Angriffen ausgenutzt
0

Verteilung nach Schweregrad

  • Kritisch 2
  • Hoch 17
  • Mittel 12

Veröffentlichungen pro Jahr

  1. 2019: 2
  2. 2020: 0
  3. 2021: 1
  4. 2022: 0
  5. 2023: 0
  6. 2024: 9
  7. 2025: 10
  8. 2026: 9
Schweregrad:
  1. Hoch · 7.5 CVE-2026-59933 >= 4.0.0, < 5.8.1, >= 3.3.0, < 3.10.7, >= 2.2.0, < 2.4.7, >= 2.0.0, < 2.1.18, < 1.30.6 5.8.1, 3.10.7, 2.4.7, 2.1.18, 1.30.6
  2. Hoch · 7.5 CVE-2026-59932 >= 4.0.0, < 5.8.1, >= 3.3.0, < 3.10.7, >= 2.2.0, < 2.4.7, >= 2.0.0, < 2.1.18, < 1.30.6 5.8.1, 3.10.7, 2.4.7, 2.1.18, 1.30.6
  3. Hoch · 7.7 CVE-2026-59931 >= 4.0.0, < 5.8.1, >= 3.3.0, < 3.10.7, >= 2.2.0, < 2.4.7, >= 2.0.0, < 2.1.18, < 1.30.6 5.8.1, 3.10.7, 2.4.7, 2.1.18, 1.30.6
  4. PHPSpreadsheet has a patch bypass for CVE-2026-34084 dieser Eintrag
    Kritisch CVE-2026-45034 < 1.30.5 1.30.5
  5. Hoch · 7.5 CVE-2026-40902 >= 4.0.0, < 5.7.0, >= 3.3.0, < 3.10.5, >= 2.2.0, < 2.4.5, >= 2.0.0, < 2.1.16, < 1.30.4 5.7.0, 3.10.5, 2.4.5, 2.1.16, 1.30.4
  6. Hoch · 7.5 CVE-2026-40863 >= 4.0.0, < 5.7.0, >= 3.3.0, < 3.10.5, >= 2.2.0, < 2.4.5, >= 2.0.0, < 2.1.16, < 1.30.4 5.7.0, 3.10.5, 2.4.5, 2.1.16, 1.30.4
  7. Kritisch CVE-2026-34084 >= 4.0.0, < 5.6.0, >= 3.3.0, < 3.10.4, >= 2.2.0, < 2.4.4, >= 2.0.0, < 2.1.15, < 1.30.3 5.6.0, 3.10.4, 2.4.4, 2.1.15, 1.30.3
  8. Hoch CVE-2025-54370 < 1.30.0, >= 2.0.0, < 2.1.12, >= 2.2.0, < 2.4.0, >= 3.0.0, < 3.10.0, >= 4.0.0, < 5.0.0 1.30.0, 2.1.12, 2.4.0, 3.10.0, 5.0.0
  9. Hoch · 7.1 CVE-2024-56409 >= 3.0.0, < 3.7.0, < 1.29.7, >= 2.0.0, < 2.1.6, >= 2.2.0, < 2.3.5 3.7.0, 1.29.7, 2.1.6, 2.3.5
  10. Hoch · 7.1 CVE-2024-56366 >= 3.0.0, < 3.7.0, < 1.29.7, >= 2.0.0, < 2.1.6, >= 2.2.0, < 2.3.5 3.7.0, 1.29.7, 2.1.6, 2.3.5
  11. Hoch · 7.1 CVE-2024-56365 >= 3.0.0, < 3.7.0, < 1.29.7, >= 2.0.0, < 2.1.6, >= 2.2.0, < 2.3.5 3.7.0, 1.29.7, 2.1.6, 2.3.5
  12. Hoch · 7.1 CVE-2024-56408 >= 3.0.0, < 3.7.0, < 1.29.7, >= 2.0.0, < 2.1.6, >= 2.2.0, < 2.3.5 3.7.0, 1.29.7, 2.1.6, 2.3.5
  13. Hoch · 7.5 CVE-2024-48917 < 1.29.4, >= 2.0.0, < 2.1.3, >= 2.2.0, < 2.3.2, >= 3.3.0, < 3.4.0 1.29.4, 2.1.3, 2.3.2, 3.4.0
  14. Hoch · 7.5 CVE-2024-47873 < 1.29.4, >= 2.0.0, < 2.1.3, >= 2.2.0, < 2.3.2, >= 3.3.0, < 3.4.0 1.29.4, 2.1.3, 2.3.2, 3.4.0
  15. Hoch · 7.7 CVE-2024-45290 >= 2.2.0, < 2.3.0, < 1.29.2, >= 2.0.0, < 2.1.1 2.3.0, 1.29.2, 2.1.1
  16. Hoch · 7.5 CVE-2024-45293 >= 2.2.0, < 2.3.0, < 1.29.1, >= 2.0.0, < 2.1.1 2.3.0, 1.29.1, 2.1.1
  17. Hoch · 8.8 CVE-2024-45048 < 1.29.1, >= 2.2.0, < 2.2.1, >= 2.0.0, < 2.1.1 1.29.1, 2.2.1, 2.1.1
  18. Hoch · 8.8 CVE-2018-19277 < 1.5.1 1.5.1

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.