From 02c8625411dcb96e1f63d58c47460284e15b2e80 Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Thu, 26 Dec 2024 21:10:37 -0800 Subject: [PATCH] Backport Html Writer Security Patches --- CHANGELOG.md | 3 ++- src/PhpSpreadsheet/Writer/Html.php | 9 ++++--- .../Writer/Html/BadCustomPropertyTest.php | 23 ++++++++++++++++++ .../Writer/Html/BadHyperlinkBaseTest.php | 23 ++++++++++++++++++ .../Writer/Html/BadHyperlinkTest.php | 23 ++++++++++++++++++ tests/data/Reader/XLSX/sec-j47r.dontuse | Bin 0 -> 8884 bytes tests/data/Reader/XLSX/sec-p66w.dontuse | Bin 0 -> 8301 bytes tests/data/Reader/XLSX/sec-q229.dontuse | Bin 0 -> 8940 bytes 8 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Html/BadCustomPropertyTest.php create mode 100644 tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkBaseTest.php create mode 100644 tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkTest.php create mode 100644 tests/data/Reader/XLSX/sec-j47r.dontuse create mode 100644 tests/data/Reader/XLSX/sec-p66w.dontuse create mode 100644 tests/data/Reader/XLSX/sec-q229.dontuse diff --git a/CHANGELOG.md b/CHANGELOG.md index feed1a0965..4eae723305 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com) and this project adheres to [Semantic Versioning](https://semver.org). -# TBD - 1.29.7 +# 2024-12-26 - 1.29.7 ### Deprecated @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). - More context options may be needed for http(s) image. Backport of [PR #4276](https://github.com/PHPOffice/PhpSpreadsheet/pull/4276) - Backported security patches for Samples. +- Backported security patches for Html Writer. ## 1.29.6 - 2024-12-08 diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php index 66a0ec89b6..000ea36b81 100644 --- a/src/PhpSpreadsheet/Writer/Html.php +++ b/src/PhpSpreadsheet/Writer/Html.php @@ -407,12 +407,12 @@ public function generateHTMLHeader($includeStyles = false) } else { $propertyValue = (string) $propertyValue; } - $html .= self::generateMeta($propertyValue, "custom.$propertyQualifier.$customProperty"); + $html .= self::generateMeta($propertyValue, htmlspecialchars("custom.$propertyQualifier.$customProperty")); } } if (!empty($properties->getHyperlinkBase())) { - $html .= ' ' . PHP_EOL; + $html .= ' ' . PHP_EOL; } $html .= $includeStyles ? $this->generateStyles(true) : $this->generatePageDeclarations(true); @@ -1519,8 +1519,9 @@ private function generateRow(Worksheet $worksheet, array $values, $row, $cellTyp // Hyperlink? if ($worksheet->hyperlinkExists($coordinate) && !$worksheet->getHyperlink($coordinate)->isInternal()) { $url = $worksheet->getHyperlink($coordinate)->getUrl(); - $urldecode = strtolower(html_entity_decode(trim($url), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8')); - $parseScheme = preg_match('/^(\\w+):/', $urldecode, $matches); + $urlDecode1 = html_entity_decode($url, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + $urlTrim = preg_replace('/^\\s+/u', '', $urlDecode1) ?? $urlDecode1; + $parseScheme = preg_match('/^([\\w\\s]+):/u', strtolower($urlTrim), $matches); if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 's3'], true)) { $cellData = htmlspecialchars($url, Settings::htmlEntityFlags()); } else { diff --git a/tests/PhpSpreadsheetTests/Writer/Html/BadCustomPropertyTest.php b/tests/PhpSpreadsheetTests/Writer/Html/BadCustomPropertyTest.php new file mode 100644 index 0000000000..a9ef67b791 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Html/BadCustomPropertyTest.php @@ -0,0 +1,23 @@ +load($infile); + $writer = new HtmlWriter($spreadsheet); + $html = $writer->generateHtmlAll(); + self::assertStringContainsString('', $html); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkBaseTest.php b/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkBaseTest.php new file mode 100644 index 0000000000..1f12bce570 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkBaseTest.php @@ -0,0 +1,23 @@ +load($infile); + $writer = new HtmlWriter($spreadsheet); + $html = $writer->generateHtmlAll(); + self::assertStringContainsString('', $html); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkTest.php b/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkTest.php new file mode 100644 index 0000000000..669594bb1c --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Html/BadHyperlinkTest.php @@ -0,0 +1,23 @@ +load($infile); + $writer = new HtmlWriter($spreadsheet); + $html = $writer->generateHtmlAll(); + self::assertStringContainsString("jav\tascript:alert()", $html); + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Reader/XLSX/sec-j47r.dontuse b/tests/data/Reader/XLSX/sec-j47r.dontuse new file mode 100644 index 0000000000000000000000000000000000000000..9914b1ffd12609756e1055090c95380b914dfceb GIT binary patch literal 8884 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 literal 0 HcmV?d00001 diff --git a/tests/data/Reader/XLSX/sec-q229.dontuse b/tests/data/Reader/XLSX/sec-q229.dontuse new file mode 100644 index 0000000000000000000000000000000000000000..edb902498776b741084eb98330e431b4d97f7f48 GIT binary patch literal 8940 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 iK#>m>A89Qjl>7Igrig|h004lE_~almB3`