CVE-2026-49260
Published: June 19th, 2026
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.
HIGH
CVSS v3: 8.2
CVSS v3: 8.2
Status
| DocFilters Release | Package | State | Justification | Comment |
|---|---|---|---|---|
| 26.3 | snappy (1.1.3) | False Positive | Code Not Present | This CVE affects the PhpWeasyPrint PHP library (pontedilana/php-weasyprint), a downstream of the KnpLabs/snappy PHP library. It is an OS command injection (CWE-78) in the PHP shell-command construction, where escapeshellarg()/is_executable() misuse lets an attacker-controlled binary path reach Process::fromShellCommandline(). Document Filters bundles the unrelated Google Snappy C++ compression library (version 1.1.3, external/snappy-1.1.3), which contains no PHP code, no escapeshellarg()/is_executable()/setBinary() logic, and no shell-command construction. No .php files exist in the codebase. Sibling CVEs CVE-2023-28115 and CVE-2026-49286 on the same PHP library are already tracked here as false positives for the same library-name confusion. |
| 26.2 | snappy (1.1.3) | Needs Triage | ||
| 26.1 | snappy (1.1.3) | Needs Triage | ||
| 25.4 | snappy (1.1.3) | Needs Triage | ||
| 25.3 | snappy (1.1.3) | Needs Triage | ||
| 25.2 | snappy (1.1.3) | Needs Triage | ||
| 25.1 | snappy (1.1.3) | Needs Triage | ||
| 24.4 | snappy (1.1.3) | Needs Triage | ||
| 24.4.0 | snappy (1.1.3) | Needs Triage | ||
| 24.3 | snappy (1.1.3) | Needs Triage | ||
| 24.2 | snappy (1.1.3) | Needs Triage | ||
| 24.1 | snappy (1.1.3) | Needs Triage | ||
| 23.3 | snappy (1.1.3) | Needs Triage | ||
| 23.2 | snappy (1.1.3) | Needs Triage | ||
| 23.1 | snappy (1.1.3) | Needs Triage | ||
| 22.4 | snappy (1.1.3) | Needs Triage | ||
| 22.3 | snappy (1.1.3) | Needs Triage | ||
| 22.2 | snappy (1.1.3) | Needs Triage | ||
| 22.1 | snappy (1.1.3) | Needs Triage | ||
| 21.11 | snappy (1.1.3) | Needs Triage | ||
| 21.8 | snappy (1.1.3) | Needs Triage | ||
| 21.5.0 | snappy (1.1.3) | Needs Triage | ||
| 21.2.0 | snappy (1.1.3) | Needs Triage | ||
| 11.4.19.3667 | snappy (1.1.3) | Needs Triage | ||
| 11.4.18.3599 | snappy (1.1.3) | Needs Triage | ||
| 11.4.16.3445 | snappy (1.1.3) | Needs Triage | ||
| 11.4.15.3368 | snappy (1.1.3) | Needs Triage | ||
| 11.4.14.3263 | snappy (1.1.3) | Needs Triage | ||
| 11.4.13.3179 | snappy (1.1.3) | Needs Triage | ||
| 11.4.12.3054 | snappy (1.1.3) | Needs Triage | ||
| 11.4.11.3040 | snappy (1.1.3) | Needs Triage | ||
| 11.4.11.2990 | snappy (1.1.3) | Needs Triage | ||
| 11.4.10.2934 | snappy (1.1.3) | Needs Triage | ||
| 11.4.9.2878 | snappy (1.1.3) | Needs Triage | ||
| 11.4.8.2822 | snappy (1.1.3) | Needs Triage |
Severity score breakdown
Attack Complexity
LOW
Attack Vector
LOCAL
Availability Impact
HIGH
Base Score
8.2
Base Severity
HIGH
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Privileges Required
HIGH
Scope
CHANGED
User Interaction
NONE
Vector String
CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
Version
3.1