Skip to content

Commit ea97c17

Browse files
authored
Merge pull request #4119 from PHPOffice/powerkiki
Security: prevent XXE (XML External Entity) when loading files
2 parents b43947f + bea2d4b commit ea97c17

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## TBD - 3.0.0
99

10+
### Security Fix
11+
12+
- Prevent XXE when loading files
13+
1014
### Added
1115

1216
- Nothing

src/PhpSpreadsheet/Reader/Security/XmlScanner.php

+18-6
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,11 @@ private static function forceString(mixed $arg): string
3535

3636
private function toUtf8(string $xml): string
3737
{
38-
$pattern = '/encoding="(.*?)"/';
39-
$result = preg_match($pattern, $xml, $matches);
40-
$charset = strtoupper($result ? $matches[1] : 'UTF-8');
41-
38+
$charset = $this->findCharSet($xml);
4239
if ($charset !== 'UTF-8') {
4340
$xml = self::forceString(mb_convert_encoding($xml, 'UTF-8', $charset));
4441

45-
$result = preg_match($pattern, $xml, $matches);
46-
$charset = strtoupper($result ? $matches[1] : 'UTF-8');
42+
$charset = $this->findCharSet($xml);
4743
if ($charset !== 'UTF-8') {
4844
throw new Reader\Exception('Suspicious Double-encoded XML, spreadsheet file load() aborted to prevent XXE/XEE attacks');
4945
}
@@ -52,6 +48,22 @@ private function toUtf8(string $xml): string
5248
return $xml;
5349
}
5450

51+
private function findCharSet(string $xml): string
52+
{
53+
$patterns = [
54+
'/encoding="([^"]*]?)"/',
55+
"/encoding='([^']*?)'/",
56+
];
57+
58+
foreach ($patterns as $pattern) {
59+
if (preg_match($pattern, $xml, $matches)) {
60+
return strtoupper($matches[1]);
61+
}
62+
}
63+
64+
return 'UTF-8';
65+
}
66+
5567
/**
5668
* Scan the XML for use of <!ENTITY to prevent XXE/XEE attacks.
5769
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding='UTF-7' standalone="yes"?>
2+
+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-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2+
<root>
3+
test: Valid
4+
</root>

0 commit comments

Comments
 (0)