CVE-2026-49359 Overview
CVE-2026-49359 affects pontedilana/php-weasyprint, a PHP library that generates PDF documents from URLs or HTML pages. Versions prior to 2.6.0 fetch option values server-side through file_get_contents() whenever the value resembles a URL, without restricting the URL scheme. The attachment option of the Pdf class is the reachable sink. An attacker who can influence the attachment value can trigger Server-Side Request Forgery (SSRF) [CWE-918] and local file disclosure, with fetched bytes embedded into the generated PDF. The issue mirrors the previously patched xsl-style-sheet flaw in KnpLabs/snappy.
Critical Impact
Attackers with the ability to influence the attachment option can read internal HTTP endpoints, cloud metadata services, and local files through file:// and php://filter/... wrappers, exfiltrating the contents inside the resulting PDF.
Affected Products
- pontedilana/php-weasyprint versions prior to 2.6.0
- PHP applications using the Pdf class attachment option with user-influenced values
- Deployments documented as one-to-one substitutes for KnpLabs/snappy
Discovery Timeline
- 2026-06-19 - CVE-2026-49359 published to NVD
- 2026-06-23 - Last updated in NVD database
Technical Details for CVE-2026-49359
Vulnerability Analysis
The vulnerability stems from how php-weasyprint handles option values that appear to be URLs. The library calls isOptionUrl(), which delegates to filter_var(..., FILTER_VALIDATE_URL). Any value passing this check is fetched server-side via file_get_contents() and embedded as content in the generated PDF.
FILTER_VALIDATE_URL accepts a wide range of schemes including http, https, ftp, file, and PHP stream wrappers such as php://. This permissive validation transforms an attacker-controlled string into a server-side fetch primitive. The attachment option of Pdf is the reachable sink in normal usage.
The code shape is inherited from KnpLabs/snappy, which patched the same class of issue in its xsl-style-sheet option under GHSA-c5fp-p67m-gq56.
Root Cause
The root cause is missing URL scheme allow-listing before server-side fetches. The library treats any RFC-valid URL as a fetchable resource without distinguishing between safe network schemes and dangerous wrappers like file:// or php://filter/.
Attack Vector
An authenticated user who can supply or influence the attachment option value provides a URL such as http://169.254.169.254/latest/meta-data/ to reach cloud instance metadata, or file:///etc/passwd and php://filter/convert.base64-encode/resource=/etc/passwd to disclose local files. The PHP process fetches the resource and embeds the bytes as a PDF attachment, which the attacker downloads.
*/
protected array $optionsWithContentCheck = [];
+ /**
+ * URL schemes the library is allowed to fetch server-side for options that
+ * accept URLs (e.g. `attachment`). Restricting these prevents SSRF and local
+ * file disclosure (file://, php://, ftp://, ...) through an attacker-controlled
+ * option value: a URL with a non-allowed scheme is treated as inline content
+ * instead of being fetched.
+ *
+ * @var list<string>
+ */
+ private array $allowedSchemes = ['http', 'https'];
+
/**
* {@inheritdoc}
+ *
+ * @param list<string>|null $allowedSchemes URL schemes allowed for options that accept URLs (e.g. 'http', 'https', 'ftp', 'file'). If null, defaults to ['http', 'https'].
*/
- public function __construct(?string $binary = null, array $options = [], ?array $env = null)
+ public function __construct(?string $binary = null, array $options = [], ?array $env = null, ?array $allowedSchemes = null)
{
$this->setDefaultExtension('pdf');
$this->setOptionsWithContentCheck();
+
+ if (null !== $allowedSchemes) {
+ $this->allowedSchemes = $allowedSchemes;
+ }
+
parent::__construct($binary, $options, $env);
Source: GitHub Commit 9582dcf. The patch introduces an allowedSchemes allow-list that defaults to http and https, treating URLs with disallowed schemes as inline content rather than fetching them.
Detection Methods for CVE-2026-49359
Indicators of Compromise
- Outbound HTTP requests from PHP application hosts to internal RFC1918 ranges or cloud metadata endpoints such as 169.254.169.254.
- Generated PDFs containing attachments whose content matches sensitive local files (e.g., /etc/passwd, application configuration, private keys).
- Application logs showing attachment option values containing file://, php://, or ftp:// schemes.
Detection Strategies
- Review web server access logs for user input fields that flow into PDF generation routines with URL-shaped values.
- Audit PHP error logs for file_get_contents() warnings referencing unexpected stream wrappers.
- Run a software composition analysis scan to identify hosts running pontedilana/php-weasyprint below version 2.6.0.
Monitoring Recommendations
- Alert on egress traffic from PDF-generation worker hosts to link-local and metadata IP addresses.
- Monitor PHP stream wrapper usage with runtime tracing or auditd rules covering the application process tree.
- Track Composer dependency manifests in source control for the affected package version range.
How to Mitigate CVE-2026-49359
Immediate Actions Required
- Upgrade pontedilana/php-weasyprint to version 2.6.0 or later using composer update pontedilana/php-weasyprint.
- Audit all call sites that pass user-influenced data into the attachment option of the Pdf class.
- Restrict outbound network egress from PDF-generation workers to required destinations only.
Patch Information
The fix is published in PhpWeasyPrint 2.6.0 and tracked under GHSA-x8g9-h984-pc36. The patch adds an allowedSchemes constructor parameter that defaults to ['http', 'https']. See the upstream commit for implementation details.
Workarounds
- Validate and allow-list user-supplied values before passing them to the attachment option, rejecting any string containing a :// scheme delimiter.
- Block outbound file://, php://, and ftp:// access at the application layer by sanitizing input prior to library invocation.
- Apply network-layer egress controls that prevent the PHP process from reaching cloud metadata services and internal management endpoints.
# Upgrade to the patched version
composer require pontedilana/php-weasyprint:^2.6.0
# Explicitly restrict allowed URL schemes when instantiating Pdf
# (php example)
# $pdf = new Pdf($binary, $options, $env, ['https']);
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

