Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit 7196784

Browse files
committed
fix(security): PdfReportWriter — strip stylesheet/font hooks + assert sandbox flags
Dompdf 3.1 has a history of SSRF / file-disclosure CVEs (CVE-2022-41343, CVE-2023-23924). The current writer correctly sets `isRemoteEnabled=false` and `isPhpEnabled=false`, but two gaps remained: 1. `<link rel="stylesheet">` and `@font-face` source declarations are honoured even with `isRemoteEnabled=false` because Dompdf resolves `file://` URLs locally. A stylesheet/font reference smuggled into the dashboard payload could read arbitrary FS paths. Strip both before handing HTML to Dompdf. 2. The sandbox flags are easy to lose in a future config refactor. Assert both are false at runtime; throw if they drift. A `composer audit` step in CI (reviewer's third recommendation) is already covered by the existing quality workflow's `Security (composer)` job — verified separately. Refs: #1419 review (concern 12) — discussion_r3187494519
1 parent ff45796 commit 7196784

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

lib/Service/Reporting/PdfReportWriter.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ public function write(array $dashboard, array $resolvedWidgets): string
5757
{
5858
$html = $this->htmlWriter->write(dashboard: $dashboard, resolvedWidgets: $resolvedWidgets);
5959

60+
// SECURITY: strip `<link rel="stylesheet">` and `@font-face`
61+
// src declarations before handing HTML to Dompdf. Dompdf
62+
// honours `file://` URLs even when `isRemoteEnabled=false`,
63+
// so a stylesheet/font reference smuggled through the
64+
// dashboard payload could read arbitrary files off the FS.
65+
$html = preg_replace(
66+
'#<link[^>]+rel\s*=\s*["\']?stylesheet["\']?[^>]*>#i',
67+
'',
68+
$html
69+
) ?? $html;
70+
$html = preg_replace(
71+
'#@font-face\s*\{[^}]*\}#i',
72+
'',
73+
$html
74+
) ?? $html;
75+
6076
$options = new Options();
6177
// No remote stylesheet/image fetches — keeps the renderer hermetic.
6278
$options->set('isRemoteEnabled', false);
@@ -66,6 +82,16 @@ public function write(array $dashboard, array $resolvedWidgets): string
6682
$options->set('defaultPaperSize', 'A4');
6783
$options->set('defaultPaperOrientation', 'portrait');
6884

85+
// SECURITY: assert sandbox flags didn't drift via a future
86+
// refactor. Dompdf has a history of SSRF / file-disclosure
87+
// CVEs (CVE-2022-41343, CVE-2023-23924); these flags are the
88+
// primary mitigation and must stay false.
89+
if ($options->getIsRemoteEnabled() !== false || $options->getIsPhpEnabled() !== false) {
90+
throw new \RuntimeException(
91+
'PdfReportWriter sandbox configuration drifted; remote-fetch / PHP execution must remain disabled.'
92+
);
93+
}
94+
6995
$dompdf = new Dompdf($options);
7096
$dompdf->loadHtml($html, 'UTF-8');
7197
$dompdf->setPaper('A4', 'portrait');

0 commit comments

Comments
 (0)