CVE-2026-49286 Overview
CVE-2026-49286 is an insecure deserialization vulnerability [CWE-502] in pontedilana/php-weasyprint, a PHP library that generates PDFs from URLs or HTML pages. The library guarded its output filename against the phar:// stream wrapper using a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so variants such as PHAR:// or Phar:// bypass the filter and reach file_exists() inside prepareOutput(). On PHP 7.4+, this triggers metadata deserialization of an attacker-controlled PHAR archive, resulting in remote code execution. This vulnerability is a patch bypass of CVE-2023-28115.
Critical Impact
Attackers can achieve remote code execution by supplying an output filename that uses a mixed-case phar:// scheme pointing to a crafted PHAR archive.
Affected Products
- pontedilana/php-weasyprint versions prior to 2.6.0
- PHP applications running PHP 7.4+ that pass user-influenced filenames to PhpWeasyPrint
- Downstream projects sharing the same flaw class as KnpLabs/snappy (GHSA-92rv-4j2h-8mjj)
Discovery Timeline
- 2026-06-19 - CVE-2026-49286 published to NVD
- 2026-06-22 - Last updated in NVD database
Technical Details for CVE-2026-49286
Vulnerability Analysis
The library accepts an output filename and validates it against a hardcoded blacklist of dangerous stream wrappers. The check rejects the lowercase string phar:// but does not normalize the scheme prior to comparison. PHP stream wrapper resolution is case-insensitive, so PHAR://archive.phar, Phar://archive.phar, and similar variants reach prepareOutput() unfiltered. Inside that method, file_exists() is invoked on the attacker-controlled path. When PHP resolves a phar:// URL, the PHAR loader parses the archive and deserializes its metadata block. An attacker who can write a PHAR archive to a readable location and influence the output filename can therefore instantiate arbitrary classes and trigger gadget chains.
Root Cause
The root cause is incomplete input validation. The blacklist uses case-sensitive string comparison while the underlying stream wrapper API is case-insensitive. This is the same class of bypass that affected KnpLabs/snappy upstream and was tracked as GHSA-92rv-4j2h-8mjj.
Attack Vector
The attack is network-reachable when an application exposes PDF generation functionality and allows user input to influence the output filename. The attacker uploads or plants a malicious PHAR file, then requests PDF generation with an output path such as PHAR:///tmp/payload.phar/file.pdf. The high attack complexity reflects the need to place the PHAR archive and identify a usable gadget chain.
// Security patch in src/AbstractGenerator.php (PhpWeasyPrint 2.6.0)
{
public const DEFAULT_TIMEOUT = 10;
+ /** @var list<string> */
+ protected const ALLOWED_PROTOCOLS = ['file'];
+
+ protected const WINDOWS_LOCAL_FILENAME_REGEX = '/^[a-z]:(?:[\\\/]?(?:[\w\s!#()-]+|[\.]{1,2})+)*[\\\/]?/i';
+
/** @var list<string> */
public array $temporaryFiles = [];
protected ?string $temporaryFolder = null;
Source: GitHub Commit d1aa4877
The patch replaces the blacklist with an allowlist that only permits the file protocol and validates Windows-style local paths with a dedicated regex, eliminating case-variant bypasses.
Detection Methods for CVE-2026-49286
Indicators of Compromise
- Requests to PDF generation endpoints containing phar://, PHAR://, Phar://, or other case variants in filename parameters
- Presence of unexpected .phar files in writable directories accessible to the web application
- PHP error logs referencing PHAR metadata unserialization or unexpected class instantiation during PDF generation
- Outbound network connections originating from PHP processes immediately after PDF generation requests
Detection Strategies
- Inspect PHP-FPM and web server logs for query parameters and POST bodies containing any case variant of phar://
- Audit calls to pontedilana/php-weasyprint to identify code paths where user input reaches the output filename argument
- Use composer show pontedilana/php-weasyprint across deployments to enumerate vulnerable versions below 2.6.0
Monitoring Recommendations
- Alert on creation of .phar files in upload directories or other web-writable paths
- Monitor child processes spawned by PHP workers for unexpected shells or system utilities following PDF generation
- Enable PHP phar.readonly = On and audit any configuration that disables it
How to Mitigate CVE-2026-49286
Immediate Actions Required
- Upgrade pontedilana/php-weasyprint to version 2.6.0 or later using composer update pontedilana/php-weasyprint
- Audit all application code that passes user-controlled values to PhpWeasyPrint output filename arguments
- Remove or quarantine any unexpected .phar files found in writable directories
Patch Information
PhpWeasyPrint 2.6.0 contains the fix. The patch in commit d1aa4877 introduces an ALLOWED_PROTOCOLS allowlist restricted to file and a Windows local-path regex, replacing the prior case-sensitive blacklist. Review the GitHub Security Advisory GHSA-2fmj-p74r-3wjm and the 2.6.0 release notes for details.
Workarounds
- Set phar.readonly = On in php.ini to prevent PHAR creation, reducing the attack surface
- Sanitize output filenames by rejecting any value containing :// regardless of case before passing to the library
- Restrict file upload directories to non-executable, non-web-readable paths and validate uploaded MIME types
# Upgrade to the patched release
composer require pontedilana/php-weasyprint:^2.6.0
# Verify installed version
composer show pontedilana/php-weasyprint | grep versions
# Harden PHP configuration
echo 'phar.readonly = On' >> /etc/php/7.4/fpm/php.ini
systemctl restart php7.4-fpm
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

