From c6ca9929c1d025727ef9f3a0123ab9f9e856267f Mon Sep 17 00:00:00 2001 From: Sixto Martin Date: Wed, 23 Jan 2019 18:57:56 +0100 Subject: [PATCH] Security improvement suggested by Nils Engelbertz to prevent DDOS by expansion of internally defined entities (XEE) --- lib/Saml2/Utils.php | 14 +++++++++---- tests/src/OneLogin/Saml2/UtilsTest.php | 28 ++++++++++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/Saml2/Utils.php b/lib/Saml2/Utils.php index da83ae20..248b954c 100644 --- a/lib/Saml2/Utils.php +++ b/lib/Saml2/Utils.php @@ -84,14 +84,20 @@ public static function loadXML($dom, $xml) assert('$dom instanceof DOMDocument'); assert('is_string($xml)'); - if (strpos($xml, 'loadXML($xml); + libxml_disable_entity_loader($oldEntityLoader); + foreach ($dom->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + throw new Exception( + 'Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks' + ); + } + } + if (!$res) { return false; } else { diff --git a/tests/src/OneLogin/Saml2/UtilsTest.php b/tests/src/OneLogin/Saml2/UtilsTest.php index 41dd8b5f..47f09772 100644 --- a/tests/src/OneLogin/Saml2/UtilsTest.php +++ b/tests/src/OneLogin/Saml2/UtilsTest.php @@ -70,9 +70,9 @@ public function testXMLAttacks() ]>&xxe;'; try { $res = OneLogin_Saml2_Utils::loadXML($dom, $attackXXE); - $this->fail('Exception was not raised'); + $this->assertFalse($res); } catch (Exception $e) { - $this->assertEquals('Detected use of ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); + $this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); } $xmlWithDTD = ' @@ -83,8 +83,12 @@ public function testXMLAttacks() test '; - $res2 = OneLogin_Saml2_Utils::loadXML($dom, $xmlWithDTD); - $this->assertTrue($res2 instanceof DOMDocument); + try { + $res2 = OneLogin_Saml2_Utils::loadXML($dom, $xmlWithDTD); + $this->assertFalse($res2); + } catch (Exception $e) { + $this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); + } $attackXEE = ' ]> @@ -93,9 +97,21 @@ public function testXMLAttacks() '; try { $res3 = OneLogin_Saml2_Utils::loadXML($dom, $attackXEE); - $this->fail('Exception was not raised'); + $this->assertFalse($res3); + } catch (Exception $e) { + $this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); + } + + $attackXEEutf16 = mb_convert_encoding(' + ]> + + This result is &harmless; + ', 'UTF-16'); + try { + $res4 = OneLogin_Saml2_Utils::loadXML($dom, $attackXEEutf16); + $this->assertFalse($res4); } catch (Exception $e) { - $this->assertEquals('Detected use of ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); + $this->assertEquals('Detected use of DOCTYPE/ENTITY in XML, disabled to prevent XXE/XEE attacks', $e->getMessage()); } }