Severity by source
AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
Attacker needs write access to the binary configuration (PR:H, AV:L), execution as PHP user escapes the library trust boundary (S:C) with full C/I/A impact on the host process.
Primary rating from Vendor (github).
CVSS VectorVendor: github
Lifecycle Timeline
3DescriptionCVE.org
PhpWeasyPrint is a PHP library allowing PDF generation from a URL or an HTML page. Prior to version 2.5.1, pontedilana/php-weasyprint builds the shell command for WeasyPrint by passing the binary path through escapeshellarg() first and then checking the *quoted* result with is_executable(). On POSIX escapeshellarg('/usr/local/bin/weasyprint') returns '/usr/local/bin/weasyprint' with the single-quote characters as part of the string, so is_executable() looks for a file whose actual name includes those quotes. That file never exists, the "safe" branch is dead code, and the raw $binary string (set via the constructor or setBinary()) flows directly into Symfony\Component\Process\Process::fromShellCommandline(). Any deployment whose binary path is sourced from configuration, an environment variable, or a per-tenant setting reaches a shell-command-injection sink. The library is documented as a one-to-one substitute for KnpLabs/snappy and inherited the exact pre-fix codepath KnpLabs patched in GHSA-vpr4-p6fq-85jc. PhpWeasyPrint version 2.5.1 contains a patch for the issue.
AnalysisAI
Shell command injection in pontedilana/php-weasyprint prior to 2.5.1 allows code execution as the PHP process when the WeasyPrint binary path is sourced from configuration, environment variables, or per-tenant settings. The library's buildCommand() inverted the order of escapeshellarg() and is_executable(), turning the 'safe' branch into dead code and passing the raw binary string into Symfony Process::fromShellCommandline(). No public exploit identified at time of analysis, but a PoC for the identical KnpLabs/snappy precursor flaw (GHSA-vpr4-p6fq-85jc) is published and directly applicable.
Technical ContextAI
PhpWeasyPrint is a PHP wrapper around the WeasyPrint HTML-to-PDF CLI, marketed as a drop-in replacement for KnpLabs/snappy. The defect is a CWE-78 OS Command Injection rooted in a logic error: escapeshellarg('/usr/local/bin/weasyprint') returns the path wrapped in literal single quotes, then is_executable() is asked whether a file literally named "'/usr/local/bin/weasyprint'" (quotes included) is executable. On POSIX that always returns false, so the ternary falls through to the unescaped $binary, which Symfony's Process::fromShellCommandline() then evaluates through /bin/sh -c. The downstream KnpLabs/snappy project patched the identical bug in 1.7.1 (GHSA-vpr4-p6fq-85jc); PhpWeasyPrint inherited the codepath verbatim. The 2.5.1 fix introduces getEscapedBinary() which calls is_executable() on the unescaped path first and throws RuntimeException before escaping.
RemediationAI
Vendor-released patch: upgrade pontedilana/php-weasyprint to 2.5.1 or later via composer update pontedilana/php-weasyprint (see https://github.com/pontedilana/php-weasyprint/releases/tag/2.5.1 and commit 9e86a2b317237fc5728f712f5037164530117f7e). If upgrade is not immediately possible, the vendor-recommended workaround mirrors the snappy guidance: validate the binary path with \is_executable($path) on the unescaped string before instantiating the generator, and reject any value that fails - note this only helps if the path is set in application code, not if it flows from runtime configuration. Additional compensating controls: remove tenant/operator write access to the binary path setting, hard-code the path in immutable application code or container image, and run the PHP-FPM process under a least-privileged UID with a restrictive AppArmor/SELinux profile so a successful injection cannot read tenant data or pivot.
In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
The '/common/download_agent_installer.php' script in the Quest KACE System Management Appliance 8.0.318 is accessible by
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
Same weakness CWE-78 – OS Command Injection
View allSame technique Command Injection
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-38048
GHSA-f5gc-qxf8-mh9g