diff --git a/typo3/sysext/adodb/Documentation/Index.rst b/typo3/sysext/adodb/Documentation/Index.rst index d1ef0980c579d18db6b878417f596dc5da48f95b..a3bae0d49d9a07028e854c47bf74198f2bbad76d 100644 --- a/typo3/sysext/adodb/Documentation/Index.rst +++ b/typo3/sysext/adodb/Documentation/Index.rst @@ -25,6 +25,7 @@ updated to upstream. - ADOdb: Allow setting NOT NULL/DEFAULT on blob and text columns (67442_) (Upstream pull request: [3]_) - ADOdb: Table names in sequences broken (64990_) - ADOdb: PHP7 redefinition of parameter (71244_) +- Security: XML entity expansion (61269_) .. [2] https://github.com/ADOdb/ADOdb/commit/85f05a98974ea85ecae943faf230a27afdbaa746 .. [3] https://github.com/ADOdb/ADOdb/pull/118 @@ -38,6 +39,7 @@ updated to upstream. .. _67442: https://forge.typo3.org/issues/67442 .. _64990: https://forge.typo3.org/issues/64990 .. _71244: https://forge.typo3.org/issues/71244 +.. _61269: https://forge.typo3.org/issues/61269 Diff diff --git a/typo3/sysext/adodb/adodb/adodb-xmlschema.inc.php b/typo3/sysext/adodb/adodb/adodb-xmlschema.inc.php index 72a9f9bc757e668a6d12224312f3d31c615cdae3..fc2c5bc9b9fc68d93b81b4f89212b9e65e910ed5 100644 --- a/typo3/sysext/adodb/adodb/adodb-xmlschema.inc.php +++ b/typo3/sysext/adodb/adodb/adodb-xmlschema.inc.php @@ -1456,6 +1456,8 @@ class adoSchema { $this->success = 2; $xmlParser = $this->create_parser(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // Process the file while( $data = fread( $fp, 4096 ) ) { @@ -1468,6 +1470,7 @@ class adoSchema { } } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free( $xmlParser ); return $this->sqlArray; @@ -1502,6 +1505,8 @@ class adoSchema { $this->success = 2; $xmlParser = $this->create_parser(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) { die( sprintf( @@ -1511,6 +1516,7 @@ class adoSchema { ) ); } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free( $xmlParser ); return $this->sqlArray; diff --git a/typo3/sysext/adodb/adodb/adodb-xmlschema03.inc.php b/typo3/sysext/adodb/adodb/adodb-xmlschema03.inc.php index 3ed5aecbe07ff5d77eb071c159a48579e42b79f3..ba190e7aeafda749cd548e4b64f6bf0357afd0ae 100644 --- a/typo3/sysext/adodb/adodb/adodb-xmlschema03.inc.php +++ b/typo3/sysext/adodb/adodb/adodb-xmlschema03.inc.php @@ -1612,6 +1612,8 @@ class adoSchema { $this->success = 2; $xmlParser = $this->create_parser(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // Process the file while( $data = fread( $fp, 4096 ) ) { @@ -1624,6 +1626,7 @@ class adoSchema { } } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free( $xmlParser ); return $this->sqlArray; @@ -1659,6 +1662,8 @@ class adoSchema { $this->success = 2; $xmlParser = $this->create_parser(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) { die( sprintf( @@ -1668,6 +1673,7 @@ class adoSchema { ) ); } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free( $xmlParser ); return $this->sqlArray; diff --git a/typo3/sysext/core/Classes/Imaging/IconProvider/SvgIconProvider.php b/typo3/sysext/core/Classes/Imaging/IconProvider/SvgIconProvider.php index d4cf6f2dcb89329b4ea0fac737c049f278226132..8e1e5e543870ebe7b4839ceeebe075b3c8826480 100644 --- a/typo3/sysext/core/Classes/Imaging/IconProvider/SvgIconProvider.php +++ b/typo3/sysext/core/Classes/Imaging/IconProvider/SvgIconProvider.php @@ -93,7 +93,10 @@ class SvgIconProvider implements IconProviderInterface $svgContent = file_get_contents($source); $svgContent = preg_replace('/<script[\s\S]*?>[\s\S]*?<\/script>/i', '', $svgContent); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); $svgElement = simplexml_load_string($svgContent); + libxml_disable_entity_loader($previousValueOfEntityLoader); // remove xml version tag $domXml = dom_import_simplexml($svgElement); diff --git a/typo3/sysext/core/Classes/Localization/Parser/AbstractXmlParser.php b/typo3/sysext/core/Classes/Localization/Parser/AbstractXmlParser.php index 801c44e58555fb432693b48d4c5a491a8b0633ec..bbd5bbdad715fbac54c7e148b820bf083f8a5405 100644 --- a/typo3/sysext/core/Classes/Localization/Parser/AbstractXmlParser.php +++ b/typo3/sysext/core/Classes/Localization/Parser/AbstractXmlParser.php @@ -91,7 +91,11 @@ abstract class AbstractXmlParser implements LocalizationParserInterface */ protected function parseXmlFile() { - $rootXmlNode = simplexml_load_file($this->sourcePath, 'SimpleXMLElement', LIBXML_NOWARNING); + $xmlContent = file_get_contents($this->sourcePath); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $rootXmlNode = simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOWARNING); + libxml_disable_entity_loader($previousValueOfEntityLoader); if (!isset($rootXmlNode) || $rootXmlNode === false) { throw new InvalidXmlFileException('The path provided does not point to existing and accessible well-formed XML file.', 1278155988); } diff --git a/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php b/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php index 328c09c53d7d9149e133600c40538f3eb70be128..d00f8beefbdb4e6b92a7462a6334190951edb5d7 100644 --- a/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php +++ b/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php @@ -167,7 +167,11 @@ class LocallangXmlParser extends AbstractXmlParser { $rootXmlNode = false; if (file_exists($targetPath)) { - $rootXmlNode = simplexml_load_file($targetPath, 'SimpleXMLElement', LIBXML_NOWARNING); + $xmlContent = file_get_contents($targetPath); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $rootXmlNode = simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOWARNING); + libxml_disable_entity_loader($previousValueOfEntityLoader); } if (!isset($rootXmlNode) || $rootXmlNode === false) { throw new InvalidXmlFileException('The path provided does not point to existing and accessible well-formed XML file (' . $targetPath . ').', 1278155987); diff --git a/typo3/sysext/core/Classes/Type/File/ImageInfo.php b/typo3/sysext/core/Classes/Type/File/ImageInfo.php index ef82186fecf0ad20d145d6a2ed4cc69add9f896c..faddaba1e34a24d6217c5d48187a8e33b8a1d3db 100644 --- a/typo3/sysext/core/Classes/Type/File/ImageInfo.php +++ b/typo3/sysext/core/Classes/Type/File/ImageInfo.php @@ -86,7 +86,11 @@ class ImageInfo extends FileInfo { $imagesSizes = array(); - $xml = simplexml_load_file($this->getPathname()); + $fileContent = file_get_contents($this->getPathname()); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $xml = simplexml_load_string($fileContent); + libxml_disable_entity_loader($previousValueOfEntityLoader); $xmlAttributes = $xml->attributes(); // First check if width+height are set diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php index 767729e79bb3a9f6138577d556047c7e7ac4a829..7c5600bb55239cc319d4a83860a4fd10e5b77d1f 100755 --- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php +++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php @@ -1647,6 +1647,8 @@ class GeneralUtility */ public static function xml2tree($string, $depth = 999, $parserOptions = array()) { + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); $parser = xml_parser_create(); $vals = array(); $index = array(); @@ -1656,6 +1658,7 @@ class GeneralUtility xml_parser_set_option($parser, $option, $value); } xml_parse_into_struct($parser, $string, $vals, $index); + libxml_disable_entity_loader($previousValueOfEntityLoader); if (xml_get_error_code($parser)) { return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)); } @@ -1895,6 +1898,8 @@ class GeneralUtility */ protected static function xml2arrayProcess($string, $NSprefix = '', $reportDocTag = false) { + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // Create parser: $parser = xml_parser_create(); $vals = array(); @@ -1909,6 +1914,7 @@ class GeneralUtility xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // Parse content: xml_parse_into_struct($parser, $string, $vals, $index); + libxml_disable_entity_loader($previousValueOfEntityLoader); // If error, return error message: if (xml_get_error_code($parser)) { return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)); diff --git a/typo3/sysext/core/Tests/FunctionalTestCase.php b/typo3/sysext/core/Tests/FunctionalTestCase.php index 1c629245765dbea3b81dfa3512826ddeb0cbebad..b5a26ec15e235c2f71b4862bea29e47040cf1dfd 100644 --- a/typo3/sysext/core/Tests/FunctionalTestCase.php +++ b/typo3/sysext/core/Tests/FunctionalTestCase.php @@ -277,7 +277,11 @@ abstract class FunctionalTestCase extends BaseTestCase $database = $this->getDatabaseConnection(); - $xml = simplexml_load_file($path); + $fileContent = file_get_contents($path); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $xml = simplexml_load_string($fileContent); + libxml_disable_entity_loader($previousValueOfEntityLoader); $foreignKeys = array(); /** @var $table \SimpleXMLElement */ diff --git a/typo3/sysext/documentation/Classes/Service/DocumentationService.php b/typo3/sysext/documentation/Classes/Service/DocumentationService.php index 680bc11da6d44b422065b1606324300f9b6e8558..ce74975dd665cb9946b72bac6779b08d3cc9056b 100644 --- a/typo3/sysext/documentation/Classes/Service/DocumentationService.php +++ b/typo3/sysext/documentation/Classes/Service/DocumentationService.php @@ -245,7 +245,10 @@ class DocumentationService */ protected function parsePackagesXML($string) { + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); $data = json_decode(json_encode((array)simplexml_load_string($string)), true); + libxml_disable_entity_loader($previousValueOfEntityLoader); if (count($data) !== 2) { throw new \TYPO3\CMS\Documentation\Exception\XmlParser('Error in XML parser while decoding packages XML file.', 1374222437); } diff --git a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php index 68daf102db14e122e53a70028c8f1b3488fb4351..3a20d88d6ef324e7f71ba71ab8fd61b6500ec53d 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/Parser/ExtensionXmlPushParser.php @@ -69,6 +69,8 @@ class ExtensionXmlPushParser extends AbstractExtensionXmlParser if (!is_resource($this->objXml)) { throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342640663); } + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // keep original character case of XML document xml_parser_set_option($this->objXml, XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($this->objXml, XML_OPTION_SKIP_WHITE, false); @@ -83,6 +85,7 @@ class ExtensionXmlPushParser extends AbstractExtensionXmlParser throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), $file), 1342640703); } } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free($this->objXml); } diff --git a/typo3/sysext/extensionmanager/Classes/Utility/Parser/MirrorXmlPushParser.php b/typo3/sysext/extensionmanager/Classes/Utility/Parser/MirrorXmlPushParser.php index f21b95ba5cfb06eccef6f7c8e4af4ec2096715cf..3e77f43b1da9bf95d1d7054c97969938b24c06e7 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/Parser/MirrorXmlPushParser.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/Parser/MirrorXmlPushParser.php @@ -64,6 +64,8 @@ class MirrorXmlPushParser extends AbstractMirrorXmlParser if (!is_resource($this->objXml)) { throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342641009); } + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // keep original character case of XML document xml_parser_set_option($this->objXml, XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($this->objXml, XML_OPTION_SKIP_WHITE, false); @@ -78,6 +80,7 @@ class MirrorXmlPushParser extends AbstractMirrorXmlParser throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), $file), 1342641011); } } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free($this->objXml); } diff --git a/typo3/sysext/lang/Classes/Service/TerService.php b/typo3/sysext/lang/Classes/Service/TerService.php index 75595baf7c89cee327aeb07649a0a62adc4aca3d..2fbd29548041f31df3fb6345a42e1e77bb37d487 100644 --- a/typo3/sysext/lang/Classes/Service/TerService.php +++ b/typo3/sysext/lang/Classes/Service/TerService.php @@ -59,12 +59,15 @@ class TerService extends TerUtility implements SingletonInterface { // Create parser: $parser = xml_parser_create(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); $values = array(); $index = array(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); // Parse content xml_parse_into_struct($parser, $string, $values, $index); + libxml_disable_entity_loader($previousValueOfEntityLoader); // If error, return error message if (xml_get_error_code($parser)) { $line = xml_get_current_line_number($parser); diff --git a/typo3/sysext/recycler/Tests/Functional/Recycle/AbstractRecycleTestCase.php b/typo3/sysext/recycler/Tests/Functional/Recycle/AbstractRecycleTestCase.php index b197e0ade0f6cb54b484fa3b4e31a08c9a54890e..11eed511da0941c02714a18361b3c0e70191a986 100644 --- a/typo3/sysext/recycler/Tests/Functional/Recycle/AbstractRecycleTestCase.php +++ b/typo3/sysext/recycler/Tests/Functional/Recycle/AbstractRecycleTestCase.php @@ -92,7 +92,11 @@ abstract class AbstractRecycleTestCase extends \TYPO3\CMS\Core\Tests\FunctionalT } $data = array(); - $xml = simplexml_load_file($path); + $fileContent = file_get_contents($path); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); + $xml = simplexml_load_string($fileContent); + libxml_disable_entity_loader($previousValueOfEntityLoader); /** @var $table \SimpleXMLElement */ foreach ($xml->children() as $table) { diff --git a/typo3/sysext/rtehtmlarea/Classes/Controller/SpellCheckingController.php b/typo3/sysext/rtehtmlarea/Classes/Controller/SpellCheckingController.php index 1babffbfefdef2a84d604263488a1f7a29f643da..2fdc2aa5f78d35582bfbd803b08ce883f825cec4 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Controller/SpellCheckingController.php +++ b/typo3/sysext/rtehtmlarea/Classes/Controller/SpellCheckingController.php @@ -316,6 +316,8 @@ class SpellCheckingController $content = GeneralUtility::_POST('content'); // Parsing the input HTML $parser = xml_parser_create(strtoupper($this->parserCharset)); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_set_object($parser, $this); if (!xml_set_element_handler($parser, 'startHandler', 'endHandler')) { @@ -333,6 +335,7 @@ class SpellCheckingController if (xml_get_error_code($parser)) { throw new \UnexpectedValueException('Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)), 1294585788); } + libxml_disable_entity_loader($previousValueOfEntityLoader); xml_parser_free($parser); if ($this->pspell_is_available && !$this->forceCommandMode) { pspell_clear_session($this->pspell_link); diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php b/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php index 547b11401df0ae4c42a15bd58d0aa592f61ae4aa..e8f03d362f2a65b7e00d3d4785e4b5351a4ae9b3 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php @@ -107,9 +107,12 @@ class MicroDataSchema extends RteHtmlAreaApi { $types = array(); $properties = array(); + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); // Load the document $document = new \DOMDocument(); $document->loadXML($string); + libxml_disable_entity_loader($previousValueOfEntityLoader); if ($document) { // Scan resource descriptions $items = $document->getElementsByTagName('Description'); diff --git a/typo3/sysext/t3editor/Classes/TypoScriptReferenceLoader.php b/typo3/sysext/t3editor/Classes/TypoScriptReferenceLoader.php index 4b1f03c22a38b068ddc3d229f74481e706813816..7948aa00029ec285532d9169cfe75a605ea230b5 100644 --- a/typo3/sysext/t3editor/Classes/TypoScriptReferenceLoader.php +++ b/typo3/sysext/t3editor/Classes/TypoScriptReferenceLoader.php @@ -75,8 +75,11 @@ class TypoScriptReferenceLoader */ protected function loadFile($filepath) { + // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept + $previousValueOfEntityLoader = libxml_disable_entity_loader(true); $this->xmlDoc = new \DOMDocument('1.0', 'utf-8'); $this->xmlDoc->load($filepath); + libxml_disable_entity_loader($previousValueOfEntityLoader); // @TODO: oliver@typo3.org: I guess this is not required here $this->xmlDoc->saveXML(); }