0) { return true; } return false; }, E_WARNING); $result = $callback($xml, $dom, LIBXML_NONET | $libXmlConstants); restore_error_handler(); // Entity load to previous setting if (!self::isPhpFpm()) { libxml_disable_entity_loader($loadEntities); libxml_use_internal_errors($useInternalXmlErrors); } if (!$result) { return false; } // Scan for potential XEE attacks using ENTITY, if not PHP-FPM if (!self::isPhpFpm()) { foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { if ($child->entities->length > 0) { throw new Exception\RuntimeException(self::ENTITY_DETECT); } } } } if (isset($simpleXml)) { $result = simplexml_import_dom($dom); if (!$result instanceof SimpleXMLElement) { return false; } return $result; } return $dom; } /** * Scan HTML string for potential XXE and XEE attacks * * @param string $xml * @param DomDocument $dom * @param int $libXmlConstants additional libxml constants to pass in * @throws Exception\RuntimeException * @return SimpleXMLElement|DomDocument|boolean */ public static function scanHtml($html, DOMDocument $dom = null, $libXmlConstants = 0) { $callback = function ($html, $dom, $constants) { return $dom->loadHtml($html, $constants); }; return self::scanString($html, $dom, $libXmlConstants, $callback); } /** * Scan XML string for potential XXE and XEE attacks * * @param string $xml * @param DomDocument $dom * @param int $libXmlConstants additional libxml constants to pass in * @throws Exception\RuntimeException * @return SimpleXMLElement|DomDocument|boolean */ public static function scan($xml, DOMDocument $dom = null, $libXmlConstants = 0) { $callback = function ($xml, $dom, $constants) { return $dom->loadXml($xml, $constants); }; return self::scanString($xml, $dom, $libXmlConstants, $callback); } /** * Scan XML file for potential XXE/XEE attacks * * @param string $file * @param DOMDocument $dom * @throws Exception\InvalidArgumentException * @return SimpleXMLElement|DomDocument */ public static function scanFile($file, DOMDocument $dom = null) { if (!file_exists($file)) { throw new Exception\InvalidArgumentException( "The file $file specified doesn't exist" ); } return self::scan(file_get_contents($file), $dom); } /** * Return true if PHP is running with PHP-FPM * * @return boolean */ public static function isPhpFpm() { if (substr(php_sapi_name(), 0, 3) === 'fpm') { return true; } return false; } }