12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\Xml;
- use DOMDocument;
- /**
- * Class Security
- */
- class Security
- {
- /**
- * Heuristic scan to detect entity in XML
- *
- * @param string $xmlContent
- * @return bool
- */
- private function heuristicScan($xmlContent)
- {
- return strpos($xmlContent, '<!ENTITY') === false;
- }
- /**
- * Return true if PHP is running with PHP-FPM
- *
- * @return bool
- */
- private function isPhpFpm()
- {
- return substr(php_sapi_name(), 0, 3) === 'fpm';
- }
- /**
- * Security check loaded XML document
- *
- * @param string $xmlContent
- * @return bool
- *
- * @SuppressWarnings(PHPMD.UnusedLocalVariable)
- */
- public function scan($xmlContent)
- {
- /**
- * If running with PHP-FPM we perform an heuristic scan
- * We cannot use libxml_disable_entity_loader because of this bug
- * @see https://bugs.php.net/bug.php?id=64938
- */
- if ($this->isPhpFpm()) {
- return $this->heuristicScan($xmlContent);
- }
- $document = new DOMDocument();
- $loadEntities = libxml_disable_entity_loader(true);
- $useInternalXmlErrors = libxml_use_internal_errors(true);
- /**
- * Load XML with network access disabled (LIBXML_NONET)
- * error disabled with @ for PHP-FPM scenario
- */
- set_error_handler(
- function ($errno, $errstr) {
- if (substr_count($errstr, 'DOMDocument::loadXML()') > 0) {
- return true;
- }
- return false;
- },
- E_WARNING
- );
- $result = (bool)$document->loadXML($xmlContent, LIBXML_NONET);
- restore_error_handler();
- // Entity load to previous setting
- libxml_disable_entity_loader($loadEntities);
- libxml_use_internal_errors($useInternalXmlErrors);
- if (!$result) {
- return false;
- }
- foreach ($document->childNodes as $child) {
- if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
- if ($child->entities->length > 0) {
- return false;
- }
- }
- }
- return true;
- }
- }
|