diff --git a/library/Zend/XmlRpc/Request.php b/library/Zend/XmlRpc/Request.php index 5b297ac1e9..3ca3eee40b 100644 --- a/library/Zend/XmlRpc/Request.php +++ b/library/Zend/XmlRpc/Request.php @@ -307,6 +307,7 @@ public function loadXml($request) $loadEntities = libxml_disable_entity_loader(true); try { $xml = new SimpleXMLElement($request); + libxml_disable_entity_loader($loadEntities); } catch (Exception $e) { // Not valid XML $this->_fault = new Zend_XmlRpc_Fault(631); @@ -320,7 +321,6 @@ public function loadXml($request) // Missing method name $this->_fault = new Zend_XmlRpc_Fault(632); $this->_fault->setEncoding($this->getEncoding()); - libxml_disable_entity_loader($loadEntities); return false; } @@ -334,7 +334,6 @@ public function loadXml($request) if (!isset($param->value)) { $this->_fault = new Zend_XmlRpc_Fault(633); $this->_fault->setEncoding($this->getEncoding()); - libxml_disable_entity_loader($loadEntities); return false; } @@ -345,7 +344,6 @@ public function loadXml($request) } catch (Exception $e) { $this->_fault = new Zend_XmlRpc_Fault(636); $this->_fault->setEncoding($this->getEncoding()); - libxml_disable_entity_loader($loadEntities); return false; } } @@ -354,7 +352,6 @@ public function loadXml($request) $this->_params = $argv; } - libxml_disable_entity_loader($loadEntities); $this->_xml = $request; return true; diff --git a/library/Zend/XmlRpc/Response.php b/library/Zend/XmlRpc/Response.php index f14305c16b..a0c51c62d6 100644 --- a/library/Zend/XmlRpc/Response.php +++ b/library/Zend/XmlRpc/Response.php @@ -176,11 +176,15 @@ public function loadXml($response) return false; } + // @see ZF-12293 - disable external entities for security purposes + $loadEntities = libxml_disable_entity_loader(true); + $useInternalXmlErrors = libxml_use_internal_errors(true); try { - $useInternalXmlErrors = libxml_use_internal_errors(true); $xml = new SimpleXMLElement($response); + libxml_disable_entity_loader($loadEntities); libxml_use_internal_errors($useInternalXmlErrors); } catch (Exception $e) { + libxml_disable_entity_loader($loadEntities); libxml_use_internal_errors($useInternalXmlErrors); // Not valid XML $this->_fault = new Zend_XmlRpc_Fault(651); @@ -205,6 +209,7 @@ public function loadXml($response) try { if (!isset($xml->params) || !isset($xml->params->param) || !isset($xml->params->param->value)) { + require_once 'Zend/XmlRpc/Value/Exception.php'; throw new Zend_XmlRpc_Value_Exception('Missing XML-RPC value in XML'); } $valueXml = $xml->params->param->value->asXML(); diff --git a/tests/Zend/XmlRpc/ResponseTest.php b/tests/Zend/XmlRpc/ResponseTest.php index a2ca1e906c..ac70087dc7 100644 --- a/tests/Zend/XmlRpc/ResponseTest.php +++ b/tests/Zend/XmlRpc/ResponseTest.php @@ -252,4 +252,19 @@ public function trackError($error) { $this->_errorOccured = true; } + + /** + * @group ZF-12293 + */ + public function testDoesNotAllowExternalEntities() + { + $payload = file_get_contents(dirname(__FILE__) . '/_files/ZF12293-response.xml'); + $payload = sprintf($payload, 'file://' . realpath(dirname(__FILE__) . '/_files/ZF12293-payload.txt')); + $this->_response->loadXml($payload); + $value = $this->_response->getReturnValue(); + $this->assertTrue(empty($value)); + if (is_string($value)) { + $this->assertNotContains('Local file inclusion', $value); + } + } } diff --git a/tests/Zend/XmlRpc/_files/ZF12293-response.xml b/tests/Zend/XmlRpc/_files/ZF12293-response.xml new file mode 100644 index 0000000000..a6ae308d44 --- /dev/null +++ b/tests/Zend/XmlRpc/_files/ZF12293-response.xml @@ -0,0 +1,10 @@ + + + +]> + + + &xxe; + +