Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessPlant file with malicious name
-
DeliveryInduce user to run pisa -s on it
-
ExploitFilename breaks os.system quoting
-
ExecutionShell executes injected commands
-
ImpactCode runs as invoking user
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization OS command sanitization, avoid shell exec
MITRE ATT&CK
2 techniques across 1 tactic: Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires that the pisa command-line tool be invoked with the -s or --start-viewer option against a file whose name is attacker-controlled and contains a double quote plus shell metacharacters; the vulnerable os.system('open "%s"') path in startViewer is reached only in that viewer-launch mode. Limiting factors: this is a local vector (AV:L) requiring the attacker to influence the processed filename, and it requires user interaction (UI:P) - a user or job must actually run the viewer. It does not affect the default programmatic HTML-to-PDF conversion API when the start-viewer feature is not used, and it runs only with the privileges of the invoking user. Affected versions are xhtml2pdf before 0.2.19. |
| Impact | This is a genuine but conditionally-exploitable command injection (CWE-78) whose real-world priority is moderate rather than urgent. The vendor-provided CVSS 4.0 vector (AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H, score 8.5) is internally consistent with the description: the flaw is LOCAL (AV:L) because it triggers only when a user runs the pisa CLI with -s/--start-viewer on an attacker-controlled file, and requires passive user interaction (UI:P) - the victim must invoke the viewer. The high impact (full C/I/A compromise as the invoking user) justifies the elevated base score. No EPSS score, KEV listing, or public exploit was provided in the input, so there is no signal of active or widespread exploitation; this is NOT confirmed actively exploited and no public exploit is identified at time of analysis. The signals are coherent - no contradiction between vector and description - but note the high CVSS is driven by impact, not by ease or reach: it is not a remotely-triggerable, mass-exploitable issue. The root cause is confirmed by the source diff (os.system with an unescaped interpolated filename, replaced by subprocess.run with an argument list). Treat as a prompt-to-patch library-update item, not a fire-drill. |
| Exploit ScenarioDerived | An attacker crafts a file with a name containing a double quote and shell metacharacters (e.g. output";id;".pdf) and gets it onto a system where someone converts/opens it. When a user or automated job runs the pisa tool with -s/--start-viewer, startViewer interpolates the filename into os.system('open "%s"'), breaking out of the quoting and executing arbitrary commands as the invoking user. No public exploit code is identified, but the fixing diff publicly documents the exact vulnerable construct. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 14, 2026
OS command injection in xhtml2pdf before 0.2.19 lets an attacker execute arbitrary OS commands as the invoking user when the pisa command-line tool is run with the -s/--start-viewer option against a file whose name contains a double quote plus shell metacharacters. The flaw lives in pisa.startViewer(), which interpolates an unescaped filename into os.system('open "%s"'); because the vulnerable path is only reached in viewer-launch mode, the default programmatic HTML-to-PDF conversion API is not affected. The vector is local and requires a user (or job) to actually launch the viewer, and no public exploit code has been identified at time of analysis - confirmed actively exploited status is not present in the available data.
RemediationAI
Upgrade to xhtml2pdf 0.2.19 or later, which replaces the shell-interpolated os.system call with argument-list invocations of subprocess.run(["open", filename]) on macOS and subprocess.run(["xdg-open", filename]) on Linux (fix commit f86380dad15b3a6810201d08755a3ee6b19d5063, PR https://github.com/xhtml2pdf/xhtml2pdf/pull/835, release https://github.com/xhtml2pdf/xhtml2pdf/releases/tag/v0.2.19). Vendor-released patch: 0.2.19. If immediate upgrade is not possible, simply stop invoking the pisa CLI with -s/--start-viewer and open generated PDFs with a separate viewer command, since the injection is unreachable from the normal conversion API - the trade-off is loss of the auto-open convenience only. As additional hardening, avoid processing untrusted, user-supplied filenames in any CLI workflow that shells out, and restrict who can place files in directories consumed by automated pisa viewer jobs, since the command executes with the privileges of the invoking user and any shell metacharacter set could be abused, not just the double quote shown in the advisory.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The root cause is CWE-78 (Improper Neutralization of Special Elements used in an OS Command), specifically shell metacharacter injection into a Python os.system() call inside pisa.startViewer(). The pre-0.2.19 code built a shell string of the form os.system('open "%s"' % filename), so a supplied filename containing a double quote could close the quoted argument and append shell metacharacters, which were then interpreted by the system shell with the privileges of the invoking user. The upstream fix (PR #835 / commit f86380dad15b3a6810201d08755a3ee6b19d5063, released in v0.2.19) abandons shell string interpolation entirely and uses subprocess.run(["open", filename]) on macOS (sys.platform == "darwin") and subprocess.run(["xdg-open", filename]) on Linux, passing the filename as a discrete argument so no shell parsing occurs. The affected package is identified by CPE cpe:2.3:a:xhtml2pdf:xhtml2pdf:*:*:*:*:*:*:*:* (all versions before 0.2.19), and the vulnerable logic is visible at xhtml2pdf/pisa.py lines ~393-400 in tag v0.2.18.
Know when Xhtml2Pdf gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Local because it needs an attacker-named file processed via the CLI (AV:L); UI:R since a user must run pisa -s; PR:N as no auth is needed; full C/I/A as code runs as the user.
Primary rating from Vendor (VulnCheck).
CVSS VectorVendor: VulnCheck
DescriptionCVE.org
xhtml2pdf before 0.2.19 contains an OS command injection vulnerability in pisa.startViewer() that allows attackers to execute commands by interpolating unescaped file names into os.system. Attackers can supply an input file whose name contains a double quote and shell metacharacters, which runs OS commands as the invoking user when the pisa tool is used with -s/--start-viewer.
Executive ViewAI
A command-injection flaw in xhtml2pdf releases prior to 0.2.19 can allow an attacker to run operating-system commands with the privileges of whoever invokes the tool, but only when the command-line viewer option is used against a maliciously named file. The widely deployed programmatic HTML-to-PDF conversion API that most applications depend on is not affected, so exposure is limited to teams and automated jobs that shell out to the pisa CLI in viewer-launch mode. Leadership should care because any affected internal tooling or user workstation could be leveraged for local privilege abuse, though the constrained attack path and lack of observed exploitation keep enterprise-wide risk moderate.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
OS command injection occurs when an application passes unsanitized user input directly into system shell commands.
EUVD-2026-101270
GHSA-p77q-xqj7-2552
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB