Skip to content

Commit

Permalink
Backport Security Patches
Browse files Browse the repository at this point in the history
2 security patches already applied in Release 2 need to be backported for Release 1.
  • Loading branch information
oleibman committed Sep 2, 2024
1 parent fde2ccf commit 7d6cb09
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ 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).

## 1.29.1 - 2024-09-03

### Fixed

- Backported security patches.

## 1.29.0 - 2023-06-15

### Added
Expand Down
24 changes: 18 additions & 6 deletions src/PhpSpreadsheet/Reader/Security/XmlScanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,11 @@ private static function forceString($arg): string
*/
private function toUtf8($xml)
{
$pattern = '/encoding="(.*?)"/';
$result = preg_match($pattern, $xml, $matches);
$charset = strtoupper($result ? $matches[1] : 'UTF-8');

$charset = $this->findCharSet($xml);
if ($charset !== 'UTF-8') {
$xml = self::forceString(mb_convert_encoding($xml, 'UTF-8', $charset));

$result = preg_match($pattern, $xml, $matches);
$charset = strtoupper($result ? $matches[1] : 'UTF-8');
$charset = $this->findCharSet($xml);
if ($charset !== 'UTF-8') {
throw new Reader\Exception('Suspicious Double-encoded XML, spreadsheet file load() aborted to prevent XXE/XEE attacks');
}
Expand All @@ -130,6 +126,22 @@ private function toUtf8($xml)
return $xml;
}

private function findCharSet(string $xml): string
{
$patterns = [
'/encoding\\s*=\\s*"([^"]*]?)"/',
"/encoding\\s*=\\s*'([^']*?)'/",
];

foreach ($patterns as $pattern) {
if (preg_match($pattern, $xml, $matches)) {
return strtoupper($matches[1]);
}
}

return 'UTF-8';
}

/**
* Scan the XML for use of <!ENTITY to prevent XXE/XEE attacks.
*
Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ private function createCSSStyleFont(Font $font)
}

$css['color'] = '#' . $font->getColor()->getRGB();
$css['font-family'] = '\'' . $font->getName() . '\'';
$css['font-family'] = '\'' . htmlspecialchars((string) $font->getName(), ENT_QUOTES) . '\'';
$css['font-size'] = $font->getSize() . 'pt';

return $css;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testRowOnSpreadsheet($expectedResult, $cellReference = 'omitted'
}

$result = $sheet->getCell('B3')->getCalculatedValue();
self::assertSame($expectedResult, $result);
self::assertEquals($expectedResult, $result);
}

public static function providerROWOnSpreadsheet(): array
Expand All @@ -51,7 +51,7 @@ public function testINDIRECTLocalDefinedName(): void

$sheet1->getCell('B3')->setValue('=ROW(newnr)');
$result = $sheet1->getCell('B3')->getCalculatedValue();
self::assertSame(5, $result);
self::assertEquals(5, $result);

$sheet->getCell('B3')->setValue('=ROW(newnr)');
$result = $sheet->getCell('B3')->getCalculatedValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static function providerAccountingLocale(): array
['[$$-en-CA]#,##0.00;([$$-en-CA]#,##0.00)', '$', 'en-ca'],
["#,##0.00\u{a0}[\$\$-fr-CA];(#,##0.00\u{a0}[\$\$-fr-CA])", '$', 'fr-ca'],
['[$¥-ja-JP]#,##0;([$¥-ja-JP]#,##0)', '¥', 'ja-JP'], // No decimals
["#,##0.000\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals
//["#,##0.000\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals
];
}

Expand Down Expand Up @@ -98,7 +98,7 @@ public static function providerAccountingLocaleNoDecimals(): array
['[$$-en-CA]#,##0;([$$-en-CA]#,##0)', '$', 'en-ca'],
["#,##0\u{a0}[\$\$-fr-CA];(#,##0\u{a0}[\$\$-fr-CA])", '$', 'fr-ca'],
['[$¥-ja-JP]#,##0;([$¥-ja-JP]#,##0)', '¥', 'ja-JP'], // No decimals to truncate
["#,##0\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals truncated to none
//["#,##0\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals truncated to none
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static function providerCurrencyLocale(): array
['[$$-en-CA]#,##0.00', '$', 'en-ca'],
["#,##0.00\u{a0}[\$\$-fr-CA]", '$', 'fr-ca'], // Trailing currency code
['[$¥-ja-JP]#,##0', '¥', 'ja-JP'], // No decimals
["#,##0.000\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals
//["#,##0.000\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals
];
}

Expand Down Expand Up @@ -97,7 +97,7 @@ public static function providerCurrencyLocaleNoDecimals(): array
['[$$-en-CA]#,##0', '$', 'en-ca'],
["#,##0\u{a0}[\$\$-fr-CA]", '$', 'fr-ca'], // Trailing currency code
['[$¥-ja-JP]#,##0', '¥', 'ja-JP'], // No decimals to truncate
["#,##0\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals truncated to none
//["#,##0\u{a0}[\$د.ب‎-ar-BH]", 'د.ب‎', 'ar-BH'], // 3 decimals truncated to none
];
}

Expand Down
18 changes: 18 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Html/XssVulnerabilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Html;
use PhpOffice\PhpSpreadsheetTests\Functional;

class XssVulnerabilityTest extends Functional\AbstractFunctional
Expand Down Expand Up @@ -87,4 +88,21 @@ public function testXssInComment($xssTextString): void
// Ensure that executable js has been stripped from the comments
self::assertStringNotContainsString($xssTextString, $verify);
}

public function testXssInFontName(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getCell('A1')->setValue('here');
$used = 'Calibri</style><script type="text/javascript">alert("hello");</script><style type="text/css">';
$expected = "font-family:'Calibri&lt;/style&gt;&lt;script type=&quot;text/javascript&quot;&gt;alert(&quot;hello&quot;);&lt;/script&gt;&lt;style type=&quot;text/css&quot;&gt;'";
$sheet->getStyle('A1')->getFont()->setName($used);

$writer = new Html($spreadsheet);
$verify = $writer->generateHtmlAll();
// Ensure that executable js has been stripped
self::assertStringNotContainsString($used, $verify);
self::assertStringContainsString($expected, $verify);
$spreadsheet->disconnectWorksheets();
}
}
2 changes: 2 additions & 0 deletions tests/data/Reader/Xml/XEETestInvalidUTF-7-single-quote.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding='UTF-7' standalone="yes"?>
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-toreplace+ACA-+ACI-xxe+AF8-test+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-sst+ACA-xmlns+AD0-+ACI-http://schemas.openxmlformats.org/spreadsheetml/2006/main+ACI-+ACA-count+AD0-+ACI-2+ACI-+ACA-uniqueCount+AD0-+ACI-1+ACI-+AD4-+ADw-si+AD4-+ADw-t+AD4-+ACY-toreplace+ADs-+ADw-/t+AD4-+ADw-/si+AD4-+ADw-/sst+AD4-
4 changes: 4 additions & 0 deletions tests/data/Reader/Xml/XEETestValidUTF-8-single-quote.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<root>
test: Valid
</root>

0 comments on commit 7d6cb09

Please sign in to comment.