Skip to content

Commit 69957ca

Browse files
committed
Security improvement suggested by Nils Engelbertz to prevent DDOS by expansion of internally defined entities (XEE)
1 parent 874516e commit 69957ca

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

src/Saml2/Utils.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,20 @@ public static function loadXML(DOMDocument $dom, $xml)
8282
assert($dom instanceof DOMDocument);
8383
assert(is_string($xml));
8484

85-
if (strpos($xml, '<!ENTITY') !== false) {
86-
throw new Exception('Detected use of ENTITY in XML, disabled to prevent XXE/XEE attacks');
87-
}
88-
8985
$oldEntityLoader = libxml_disable_entity_loader(true);
86+
9087
$res = $dom->loadXML($xml);
88+
9189
libxml_disable_entity_loader($oldEntityLoader);
9290

91+
foreach ($dom->childNodes as $child) {
92+
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
93+
throw new Exception(
94+
'Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks'
95+
);
96+
}
97+
}
98+
9399
if (!$res) {
94100
return false;
95101
} else {

tests/src/OneLogin/Saml2/UtilsTest.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function testXMLAttacks()
6060
$res = Utils::loadXML($dom, $attackXXE);
6161
$this->fail('Exception was not raised');
6262
} catch (Exception $e) {
63-
$this->assertEquals('Detected use of ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
63+
$this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
6464
}
6565

6666
$xmlWithDTD = '<?xml version="1.0"?>
@@ -71,8 +71,12 @@ public function testXMLAttacks()
7171
<results>
7272
<result>test</result>
7373
</results>';
74-
$res2 = Utils::loadXML($dom, $xmlWithDTD);
75-
$this->assertTrue($res2 instanceof DOMDocument);
74+
try {
75+
$res2 = Utils::loadXML($dom, $xmlWithDTD);
76+
$this->assertFalse($res2);
77+
} catch (Exception $e) {
78+
$this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
79+
}
7680

7781
$attackXEE = '<?xml version="1.0"?>
7882
<!DOCTYPE results [<!ENTITY harmless "completely harmless">]>
@@ -81,9 +85,21 @@ public function testXMLAttacks()
8185
</results>';
8286
try {
8387
$res3 = Utils::loadXML($dom, $attackXEE);
84-
$this->fail('Exception was not raised');
88+
$this->assertFalse($res3);
89+
} catch (Exception $e) {
90+
$this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
91+
}
92+
93+
$attackXEEutf16 = mb_convert_encoding('<?xml version="1.0" encoding="UTF-16"?>
94+
<!DOCTYPE results [<!ENTITY harmless "completely harmless">]>
95+
<results>
96+
<result>This result is &harmless;</result>
97+
</results>', 'UTF-16');
98+
try {
99+
$res4 = Utils::loadXML($dom, $attackXEEutf16);
100+
$this->assertFalse($res4);
85101
} catch (Exception $e) {
86-
$this->assertEquals('Detected use of ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
102+
$this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage());
87103
}
88104
}
89105

0 commit comments

Comments
 (0)