Skip to content
This repository has been archived by the owner on May 16, 2018. It is now read-only.

Commit

Permalink
Fix for XML XXE/XEE potential attacks
Browse files Browse the repository at this point in the history
  • Loading branch information
ezimuel authored and weierophinney committed Mar 6, 2014
1 parent 3a5de7c commit ff7eddd
Show file tree
Hide file tree
Showing 58 changed files with 717 additions and 225 deletions.
5 changes: 4 additions & 1 deletion library/Zend/Amf/Adobe/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
/** @see Zend_Auth_Result */
require_once 'Zend/Auth/Result.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* This class implements authentication against XML file with roles for Flex Builder.
*
Expand Down Expand Up @@ -61,7 +64,7 @@ class Zend_Amf_Adobe_Auth extends Zend_Amf_Auth_Abstract
public function __construct($rolefile)
{
$this->_acl = new Zend_Acl();
$xml = simplexml_load_file($rolefile);
$xml = Zend_Xml_Security::scanFile($rolefile);
/*
Roles file format:
<roles>
Expand Down
5 changes: 4 additions & 1 deletion library/Zend/Amf/Parse/Amf0/Deserializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
/** Zend_Amf_Constants */
require_once 'Zend/Amf/Constants.php';

/** Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/** @see Zend_Amf_Parse_Deserializer */
require_once 'Zend/Amf/Parse/Deserializer.php';

Expand Down Expand Up @@ -248,7 +251,7 @@ public function readDate()
public function readXmlString()
{
$string = $this->_stream->readLongUTF();
return simplexml_load_string($string);
return Zend_Xml_Security::scan($string); //simplexml_load_string($string);
}

/**
Expand Down
5 changes: 4 additions & 1 deletion library/Zend/Amf/Parse/Amf3/Deserializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
/** Zend_Amf_Parse_Deserializer */
require_once 'Zend/Amf/Parse/Deserializer.php';

/** Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/** Zend_Amf_Parse_TypeLoader */
require_once 'Zend/Amf/Parse/TypeLoader.php';

Expand Down Expand Up @@ -417,6 +420,6 @@ public function readXmlString()
$xmlReference = $this->readInteger();
$length = $xmlReference >> 1;
$string = $this->_stream->readBytes($length);
return simplexml_load_string($string);
return Zend_Xml_Security::scan($string);
}
}
2 changes: 1 addition & 1 deletion library/Zend/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ protected function _assertValidExtend($extendingSection, $extendedSection)
* @param string $errfile
* @param integer $errline
*/
protected function _loadFileErrorHandler($errno, $errstr, $errfile, $errline)
public function _loadFileErrorHandler($errno, $errstr, $errfile, $errline)
{
if ($this->_loadFileErrorStr === null) {
$this->_loadFileErrorStr = $errstr;
Expand Down
22 changes: 20 additions & 2 deletions library/Zend/Config/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
*/
require_once 'Zend/Config.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/** @see Zend_Xml_Exception */
require_once 'Zend/Xml/Exception.php';

/**
* XML Adapter for Zend_Config
*
Expand Down Expand Up @@ -96,9 +102,21 @@ public function __construct($xml, $section = null, $options = false)

set_error_handler(array($this, '_loadFileErrorHandler')); // Warnings and errors are suppressed
if (strstr($xml, '<?xml')) {
$config = simplexml_load_string($xml);
$config = Zend_Xml_Security::scan($xml);
} else {
$config = simplexml_load_file($xml);
try {
if (!$config = Zend_Xml_Security::scanFile($xml)) {
require_once 'Zend/Config/Exception.php';
throw new Zend_Config_Exception(
"Error failed to load $xml file"
);
}
} catch (Zend_Xml_Exception $e) {
require_once 'Zend/Config/Exception.php';
throw new Zend_Config_Exception(
$e->getMessage()
);
}
}

restore_error_handler();
Expand Down
26 changes: 15 additions & 11 deletions library/Zend/Dom/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
*/
require_once 'Zend/Dom/Query/Result.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/** @see Zend_Xml_Exception */
require_once 'Zend/Xml/Exception.php';

/**
* Query DOM structures based on CSS selectors and/or XPath
*
Expand Down Expand Up @@ -245,7 +251,6 @@ public function queryXpath($xpathQuery, $query = null)

$encoding = $this->getEncoding();
libxml_use_internal_errors(true);
libxml_disable_entity_loader(true);
if (null === $encoding) {
$domDoc = new DOMDocument('1.0');
} else {
Expand All @@ -254,14 +259,14 @@ public function queryXpath($xpathQuery, $query = null)
$type = $this->getDocumentType();
switch ($type) {
case self::DOC_XML:
$success = $domDoc->loadXML($document);
foreach ($domDoc->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
require_once 'Zend/Dom/Exception.php';
throw new Zend_Dom_Exception(
'Invalid XML: Detected use of illegal DOCTYPE'
);
}
try {
$domDoc = Zend_Xml_Security::scan($document, $domDoc);
$success = ($domDoc !== false);
} catch (Zend_Xml_Exception $e) {
require_once 'Zend/Dom/Exception.php';
throw new Zend_Dom_Exception(
$e->getMessage()
);
}
break;
case self::DOC_HTML:
Expand All @@ -275,15 +280,14 @@ public function queryXpath($xpathQuery, $query = null)
$this->_documentErrors = $errors;
libxml_clear_errors();
}
libxml_disable_entity_loader(false);
libxml_use_internal_errors(false);

if (!$success) {
require_once 'Zend/Dom/Exception.php';
throw new Zend_Dom_Exception(sprintf('Error parsing document (type == %s)', $type));
}

$nodeList = $this->_getNodeList($domDoc, $xpathQuery);
$nodeList = $this->_getNodeList($domDoc, $xpathQuery);
return new Zend_Dom_Query_Result($query, $xpathQuery, $domDoc, $nodeList);
}

Expand Down
15 changes: 6 additions & 9 deletions library/Zend/Feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
* @version $Id$
*/

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* Feed utility class
Expand Down Expand Up @@ -190,20 +192,15 @@ public static function import($uri)
*/
public static function importString($string)
{
// Load the feed as an XML DOMDocument object
$libxml_errflag = libxml_use_internal_errors(true);
$libxml_entity_loader = libxml_disable_entity_loader(true);
$doc = new DOMDocument;
if (trim($string) == '') {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Document/string being imported'
. ' is an Empty string or comes from an empty HTTP response');
}
$status = $doc->loadXML($string);
libxml_disable_entity_loader($libxml_entity_loader);
libxml_use_internal_errors($libxml_errflag);
$doc = new DOMDocument;
$doc = Zend_Xml_Security::scan($string, $doc);

if (!$status) {
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
// Build error message
$error = libxml_get_last_error();
Expand Down Expand Up @@ -320,7 +317,7 @@ public static function findFeeds($uri)
if (!mb_check_encoding($link, 'UTF-8')) {
$link = mb_convert_encoding($link, 'UTF-8');
}
$xml = @simplexml_load_string(rtrim($link, ' /') . ' />');
$xml = @Zend_Xml_Security::scan(rtrim($link, ' /') . ' />');
if ($xml === false) {
continue;
}
Expand Down
17 changes: 7 additions & 10 deletions library/Zend/Feed/Abstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
*/
require_once 'Zend/Feed/Element.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* The Zend_Feed_Abstract class is an abstract class representing feeds.
Expand Down Expand Up @@ -111,10 +113,10 @@ public function __wakeup()
{
@ini_set('track_errors', 1);
$doc = new DOMDocument;
$status = @$doc->loadXML($this->_element);
$doc = @Zend_Xml_Security::scan($this->_element, $doc);
@ini_restore('track_errors');

if (!$status) {
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
Expand Down Expand Up @@ -268,20 +270,15 @@ abstract public function send();
*/
protected function _importFeedFromString($feed)
{
// Load the feed as an XML DOMDocument object
$libxml_errflag = libxml_use_internal_errors(true);
$libxml_entity_loader = libxml_disable_entity_loader(true);
$doc = new DOMDocument;
if (trim($feed) == '') {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Remote feed being imported'
. ' is an Empty string or comes from an empty HTTP response');
}
$status = $doc->loadXML($feed);
libxml_disable_entity_loader($libxml_entity_loader);
libxml_use_internal_errors($libxml_errflag);
$doc = new DOMDocument;
$doc = Zend_Xml_Security::scan($feed, $doc);

if (!$status) {
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
// Build error message
$error = libxml_get_last_error();
Expand Down
6 changes: 4 additions & 2 deletions library/Zend/Feed/Entry/Abstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
require_once 'Zend/Feed/Element.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* Zend_Feed_Entry_Abstract represents a single entry in an Atom or RSS
Expand Down Expand Up @@ -80,10 +82,10 @@ public function __construct($uri = null, $element = null)
// Load the feed as an XML DOMDocument object
@ini_set('track_errors', 1);
$doc = new DOMDocument();
$status = @$doc->loadXML($element);
$doc = @Zend_Xml_Security::scan($element, $doc);
@ini_restore('track_errors');

if (!$status) {
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
Expand Down
6 changes: 4 additions & 2 deletions library/Zend/Feed/Entry/Atom.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
*/
require_once 'Zend/Feed/Entry/Abstract.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* Concrete class for working with Atom entries.
Expand Down Expand Up @@ -194,10 +196,10 @@ public function save($postUri = null)
// Update internal properties using $client->responseBody;
@ini_set('track_errors', 1);
$newEntry = new DOMDocument;
$status = @$newEntry->loadXML($response->getBody());
$newEntry = @Zend_Xml_Security::scan($response->getBody(), $newEntry);
@ini_restore('track_errors');

if (!$status) {
if (!$newEntry) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
Expand Down
51 changes: 25 additions & 26 deletions library/Zend/Feed/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
*/
require_once 'Zend/Feed/Reader/FeedSet.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/** @see Zend_Xml_Exception */
require_once 'Zend/Xml/Exception.php';

/**
* @category Zend
* @package Zend_Feed_Reader
Expand Down Expand Up @@ -326,29 +332,23 @@ public static function importFeed(Zend_Feed_Abstract $feed)
}

/**
* Import a feed froma string
* Import a feed from a string
*
* @param string $string
* @return Zend_Feed_Reader_FeedInterface
*/
public static function importString($string)
{
$libxml_errflag = libxml_use_internal_errors(true);
$oldValue = libxml_disable_entity_loader(true);
$dom = new DOMDocument;
$status = $dom->loadXML($string);
foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception(
'Invalid XML: Detected use of illegal DOCTYPE'
);
}
try {
$dom = Zend_Xml_Security::scan($string, $dom);
} catch (Zend_Xml_Exception $e) {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception(
$e->getMessage()
);
}
libxml_disable_entity_loader($oldValue);
libxml_use_internal_errors($libxml_errflag);

if (!$status) {
if (!$dom) {
// Build error message
$error = libxml_get_last_error();
if ($error && $error->message) {
Expand Down Expand Up @@ -455,20 +455,19 @@ public static function detectType($feed, $specOnly = false)
$dom = $feed;
} elseif(is_string($feed) && !empty($feed)) {
@ini_set('track_errors', 1);
$oldValue = libxml_disable_entity_loader(true);
//$oldValue = libxml_disable_entity_loader(true);
$dom = new DOMDocument;
$status = @$dom->loadXML($feed);
foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception(
'Invalid XML: Detected use of illegal DOCTYPE'
);
}
try {
$dom = Zend_Xml_Security::scan($feed, $dom);
} catch (Zend_Xml_Exception $e) {
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception(
$e->getMessage()
);
}
libxml_disable_entity_loader($oldValue);
//libxml_disable_entity_loader($oldValue);
@ini_restore('track_errors');
if (!$status) {
if (!$dom) {
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
Expand Down
8 changes: 6 additions & 2 deletions library/Zend/Feed/Writer/Renderer/Entry/Atom.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@

require_once 'Zend/Feed/Writer/Renderer/Feed/Atom/Source.php';

/** @see Zend_Xml_Security */
require_once 'Zend/Xml/Security.php';

/**
* @category Zend
* @package Zend_Feed_Writer
Expand Down Expand Up @@ -389,8 +392,9 @@ protected function _loadXhtml($content)
"/(<[\/]?)([a-zA-Z]+)/"
), '$1xhtml:$2', $xhtml);
$dom = new DOMDocument('1.0', $this->getEncoding());
$dom->loadXML('<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">'
. $xhtml . '</xhtml:div>');

$dom = Zend_Xml_Security::scan('<xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">'
. $xhtml . '</xhtml:div>', $dom);
return $dom->documentElement;
}

Expand Down
Loading

0 comments on commit ff7eddd

Please # to comment.