From 886647d1caf7181e947a2e771600d1addfaf53ac Mon Sep 17 00:00:00 2001
From: Bernhard Posselt
Date: Mon, 24 Nov 2014 12:23:38 +0100
Subject: update zendxml
---
articleenhancer/globalarticleenhancer.php | 7 +-
articleenhancer/xpatharticleenhancer.php | 20 +--
vendor/ZendXml/.gitignore | 5 +
vendor/ZendXml/.travis.yml | 29 ++++
vendor/ZendXml/README.md | 50 +++++++
vendor/ZendXml/composer.json | 11 +-
.../ZendXml/Exception/InvalidArgumentException.php | 4 +-
.../library/ZendXml/Exception/RuntimeException.php | 4 +-
vendor/ZendXml/library/ZendXml/Security.php | 51 +++++--
vendor/ZendXml/tests/Bootstrap.php | 92 +++++++++++++
vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php | 152 +++++++++++++++++++++
vendor/ZendXml/tests/phpunit.xml.dist | 27 ++++
vendor/ZendXml/vendor/autoload.php | 2 +-
.../vendor/composer/autoload_namespaces.php | 2 +-
vendor/ZendXml/vendor/composer/autoload_psr4.php | 1 +
vendor/ZendXml/vendor/composer/autoload_real.php | 8 +-
16 files changed, 423 insertions(+), 42 deletions(-)
create mode 100644 vendor/ZendXml/.gitignore
create mode 100644 vendor/ZendXml/.travis.yml
create mode 100644 vendor/ZendXml/README.md
create mode 100644 vendor/ZendXml/tests/Bootstrap.php
create mode 100644 vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php
create mode 100755 vendor/ZendXml/tests/phpunit.xml.dist
diff --git a/articleenhancer/globalarticleenhancer.php b/articleenhancer/globalarticleenhancer.php
index 4c01a238c..1939ca41c 100644
--- a/articleenhancer/globalarticleenhancer.php
+++ b/articleenhancer/globalarticleenhancer.php
@@ -32,10 +32,9 @@ class GlobalArticleEnhancer implements ArticleEnhancer {
// inside tags
$body = '
' . $item->getBody() . '
';
- Security::scan($body, $dom, function ($xml, $dom) {
- return @$dom->loadHTML($xml, LIBXML_HTML_NOIMPLIED
- | LIBXML_HTML_NODEFDTD | LIBXML_NONET);
- });
+ $isOk = Security::scanHtml(
+ $body, $dom, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
+ );
$xpath = new \DOMXpath($dom);
diff --git a/articleenhancer/xpatharticleenhancer.php b/articleenhancer/xpatharticleenhancer.php
index 871752856..aa94eec54 100644
--- a/articleenhancer/xpatharticleenhancer.php
+++ b/articleenhancer/xpatharticleenhancer.php
@@ -70,9 +70,7 @@ class XPathArticleEnhancer implements ArticleEnhancer {
$dom = new DOMDocument();
- Security::scan($body, $dom, function ($xml, $dom) {
- return @$dom->loadHTML($xml, LIBXML_NONET);
- });
+ $isOk = Security::scanHtml($body, $dom);
$xpath = new DOMXpath($dom);
$xpathResult = $xpath->evaluate($search);
@@ -121,14 +119,16 @@ class XPathArticleEnhancer implements ArticleEnhancer {
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
- $isOk = Security::scan($xmlString, $dom, function ($xml, $dom) {
- // wrap in div to prevent loadHTML from inserting weird elements
- $xml = '' . $xml . '
';
- return @$dom->loadHTML($xml, LIBXML_NONET | LIBXML_HTML_NODEFDTD
- | LIBXML_HTML_NOIMPLIED);
- });
+ if($xmlString === '') {
+ return false;
+ }
+
+ $xmlString = '' . $xmlString . '
';
+ $isOk = Security::scanHtml(
+ $xmlString, $dom, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
+ );
- if($xmlString === '' || !$isOk) {
+ if(!$isOk) {
return false;
}
diff --git a/vendor/ZendXml/.gitignore b/vendor/ZendXml/.gitignore
new file mode 100644
index 000000000..0a4f6e27f
--- /dev/null
+++ b/vendor/ZendXml/.gitignore
@@ -0,0 +1,5 @@
+composer.lock
+vendor
+.buildpath
+.project
+.settings
diff --git a/vendor/ZendXml/.travis.yml b/vendor/ZendXml/.travis.yml
new file mode 100644
index 000000000..ad8db966f
--- /dev/null
+++ b/vendor/ZendXml/.travis.yml
@@ -0,0 +1,29 @@
+language: php
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+matrix:
+ allow_failures:
+ - php: hhvm
+
+before_install:
+ # need to update libxml to 2.7.8 to be able to run tests using the
+ # LIBXML_HTML_NODEFDTD and LIBXML_HTML_NOIMPLIED libxml constant
+ - sudo apt-get update
+ - sudo apt-get -o DPkg::Options::="--force-confold" -y upgrade
+
+before_script:
+ - composer self-update
+ - composer install --dev
+
+script:
+ - ./vendor/bin/phpunit -c ./tests
+ - ./vendor/bin/phpcs --standard=PSR2 --ignore=tests/Bootstrap.php library tests
+
+notifications:
+ irc: "irc.freenode.org#zftalk.dev"
+ email: false
diff --git a/vendor/ZendXml/README.md b/vendor/ZendXml/README.md
new file mode 100644
index 000000000..2c67008da
--- /dev/null
+++ b/vendor/ZendXml/README.md
@@ -0,0 +1,50 @@
+ZendXml
+=======
+
+An utility component for XML usage and best practices in PHP
+
+Installation
+------------
+
+You can install using:
+
+```
+curl -s https://getcomposer.org/installer | php
+php composer.phar install
+```
+
+Notice that this library doesn't have any external dependencies, the usage of composer is for autoloading and standard purpose.
+
+
+ZendXml\Security
+----------------
+
+This is a security component to prevent [XML eXternal Entity](https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing) (XXE) and [XML Entity Expansion](http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion) (XEE) attacks on XML documents.
+
+The XXE attack is prevented disabling the load of external entities in the libxml library used by PHP, using the function [libxml_disable_entity_loader](http://www.php.net/manual/en/function.libxml-disable-entity-loader.php).
+
+The XEE attack is prevented looking inside the XML document for ENTITY usage. If the XML document uses ENTITY the library throw an Exception.
+
+We have two static methods to scan and load XML document from a string (scan) and from a file (scanFile). You can decide to get a SimpleXMLElement or DOMDocument as result, using the following use cases:
+
+```php
+use ZendXml\Security as XmlSecurity;
+
+$xml = <<
+
+ test
+
+XML;
+
+// SimpleXML use case
+$simplexml = XmlSecurity::scan($xml);
+printf ("SimpleXMLElement: %s\n", ($simplexml instanceof \SimpleXMLElement) ? 'yes' : 'no');
+
+// DOMDocument use case
+$dom = new \DOMDocument('1.0');
+$dom = XmlSecurity::scan($xml, $dom);
+printf ("DOMDocument: %s\n", ($dom instanceof \DOMDocument) ? 'yes' : 'no');
+```
+
+
diff --git a/vendor/ZendXml/composer.json b/vendor/ZendXml/composer.json
index 3b4ca91de..139f1e23b 100644
--- a/vendor/ZendXml/composer.json
+++ b/vendor/ZendXml/composer.json
@@ -11,7 +11,12 @@
"homepage": "http://packages.zendframework.com/",
"autoload": {
"psr-0": {
- "ZendXml": "library/"
+ "ZendXml\\": "library/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "ZendTest\\Xml\\": "tests/ZendXmlTest/"
}
},
"repositories": [
@@ -29,7 +34,7 @@
}
},
"require-dev": {
- "fabpot/php-cs-fixer": "*@dev",
- "phpunit/phpunit": "~3.7"
+ "phpunit/phpunit": "~3.7",
+ "squizlabs/php_codesniffer": "~1.5"
}
}
diff --git a/vendor/ZendXml/library/ZendXml/Exception/InvalidArgumentException.php b/vendor/ZendXml/library/ZendXml/Exception/InvalidArgumentException.php
index 819fb9f6e..0fef6b298 100644
--- a/vendor/ZendXml/library/ZendXml/Exception/InvalidArgumentException.php
+++ b/vendor/ZendXml/library/ZendXml/Exception/InvalidArgumentException.php
@@ -12,8 +12,6 @@ namespace ZendXml\Exception;
/**
* Invalid argument exception
*/
-class InvalidArgumentException
- extends \InvalidArgumentException
- implements ExceptionInterface
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
diff --git a/vendor/ZendXml/library/ZendXml/Exception/RuntimeException.php b/vendor/ZendXml/library/ZendXml/Exception/RuntimeException.php
index 1d5f50625..b730da4ff 100644
--- a/vendor/ZendXml/library/ZendXml/Exception/RuntimeException.php
+++ b/vendor/ZendXml/library/ZendXml/Exception/RuntimeException.php
@@ -12,8 +12,6 @@ namespace ZendXml\Exception;
/**
* Runtime exception
*/
-class RuntimeException
- extends \RuntimeException
- implements ExceptionInterface
+class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
diff --git a/vendor/ZendXml/library/ZendXml/Security.php b/vendor/ZendXml/library/ZendXml/Security.php
index d258311f4..e97a54d77 100644
--- a/vendor/ZendXml/library/ZendXml/Security.php
+++ b/vendor/ZendXml/library/ZendXml/Security.php
@@ -33,17 +33,12 @@ class Security
*
* @param string $xml
* @param DomDocument $dom
- * @param Callable(
- * @param $xml
- * @param $dom
- * @return DomDocument|boolean
- * ) $loadCallback if given allows to customize the load command e.g.:
- * function ($xml, $dom) { return $dom->loadHTML($xml, LIBXML_NONET); }
+ * @param int $libXmlConstants additional libxml constants to pass in
+ * @param Callable $callback the callback to use to create the dom element
* @throws Exception\RuntimeException
* @return SimpleXMLElement|DomDocument|boolean
*/
- public static function scan($xml, DOMDocument $dom = null,
- $loadCallback = null)
+ private static function scanString($xml, $dom, $libXmlConstants, $callback)
{
// If running with PHP-FPM we perform an heuristic scan
// We cannot use libxml_disable_entity_loader because of this bug
@@ -71,11 +66,7 @@ class Security
return false;
}, E_WARNING);
- if ($loadCallback) {
- $result = $loadCallback($xml, $dom);
- } else {
- $result = $dom->loadXml($xml, LIBXML_NONET);
- }
+ $result = $callback($xml, $dom, LIBXML_NONET | $libXmlConstants);
restore_error_handler();
@@ -110,6 +101,40 @@ class Security
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
*
diff --git a/vendor/ZendXml/tests/Bootstrap.php b/vendor/ZendXml/tests/Bootstrap.php
new file mode 100644
index 000000000..a9d0e6a55
--- /dev/null
+++ b/vendor/ZendXml/tests/Bootstrap.php
@@ -0,0 +1,92 @@
+addDirectoryToWhitelist($zfCoreLibrary . '/' . $lastArg);
+ } elseif (is_file($zfCoreTests . '/' . $lastArg)) {
+ $codeCoverageFilter->addDirectoryToWhitelist(dirname($zfCoreLibrary . '/' . $lastArg));
+ } else {
+ $codeCoverageFilter->addDirectoryToWhitelist($zfCoreLibrary);
+ }
+
+ /*
+ * Omit from code coverage reports the contents of the tests directory
+ */
+ $codeCoverageFilter->addDirectoryToBlacklist($zfCoreTests, '');
+ $codeCoverageFilter->addDirectoryToBlacklist(PEAR_INSTALL_DIR, '');
+ $codeCoverageFilter->addDirectoryToBlacklist(PHP_LIBDIR, '');
+
+ unset($codeCoverageFilter);
+}
+
+/*
+ * Unset global variables that are no longer needed.
+ */
+unset($phpUnitVersion);
diff --git a/vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php b/vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php
new file mode 100644
index 000000000..0f0fbffba
--- /dev/null
+++ b/vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php
@@ -0,0 +1,152 @@
+
+]>
+
+ This result is &harmless;
+
+XML;
+
+ $this->setExpectedException('ZendXml\Exception\RuntimeException');
+ $result = XmlSecurity::scan($xml);
+ }
+
+ public function testScanForXXE()
+ {
+ $file = tempnam(sys_get_temp_dir(), 'ZendXml_Security');
+ file_put_contents($file, 'This is a remote content!');
+ $xml = <<
+
+]>
+
+ &foo;
+
+XML;
+
+ try {
+ $result = XmlSecurity::scan($xml);
+ } catch (Exception\RuntimeException $e) {
+ unlink($file);
+ return;
+ }
+ $this->fail('An expected exception has not been raised.');
+ }
+
+ public function testScanSimpleXmlResult()
+ {
+ $result = XmlSecurity::scan($this->getXml());
+ $this->assertTrue($result instanceof SimpleXMLElement);
+ $this->assertEquals($result->result, 'test');
+ }
+
+ public function testScanDom()
+ {
+ $dom = new DOMDocument('1.0');
+ $result = XmlSecurity::scan($this->getXml(), $dom);
+ $this->assertTrue($result instanceof DOMDocument);
+ $node = $result->getElementsByTagName('result')->item(0);
+ $this->assertEquals($node->nodeValue, 'test');
+ }
+
+ /**
+ * @requires PHP 5.4
+ */
+ public function testScanDomHTML()
+ {
+ // loadHtml accepts constants in php >= 5.4
+ // http://php.net/manual/de/domdocument.loadhtml.php
+ $dom = new DOMDocument('1.0');
+ $html = <<a simple test
+HTML;
+ $constants = LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED;
+ $result = XmlSecurity::scanHtml($html, $dom, $constants);
+ $this->assertTrue($result instanceof DOMDocument);
+ $this->assertEquals($html, trim($result->saveHtml()));
+ }
+
+ public function testScanInvalidXml()
+ {
+ $xml = <<test
+XML;
+
+ $result = XmlSecurity::scan($xml);
+ $this->assertFalse($result);
+ }
+
+ public function testScanInvalidXmlDom()
+ {
+ $xml = <<test
+XML;
+
+ $dom = new DOMDocument('1.0');
+ $result = XmlSecurity::scan($xml, $dom);
+ $this->assertFalse($result);
+ }
+
+ public function testScanFile()
+ {
+ $file = tempnam(sys_get_temp_dir(), 'ZendXml_Security');
+ file_put_contents($file, $this->getXml());
+
+ $result = XmlSecurity::scanFile($file);
+ $this->assertTrue($result instanceof SimpleXMLElement);
+ $this->assertEquals($result->result, 'test');
+ unlink($file);
+ }
+
+ public function testScanXmlWithDTD()
+ {
+ $xml = <<
+
+
+]>
+
+ test
+
+XML;
+
+ $dom = new DOMDocument('1.0');
+ $result = XmlSecurity::scan($xml, $dom);
+ $this->assertTrue($result instanceof DOMDocument);
+ $this->assertTrue($result->validate());
+ }
+
+ protected function getXml()
+ {
+ return <<
+
+ test
+
+XML;
+ }
+}
diff --git a/vendor/ZendXml/tests/phpunit.xml.dist b/vendor/ZendXml/tests/phpunit.xml.dist
new file mode 100755
index 000000000..069784bd7
--- /dev/null
+++ b/vendor/ZendXml/tests/phpunit.xml.dist
@@ -0,0 +1,27 @@
+
+
+
+ ./ZendXmlTest
+ ./ZendXmlTest/TestAsset
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./ZendXmlTest
+ ../vendor
+
+
+
+
+
+
+
diff --git a/vendor/ZendXml/vendor/autoload.php b/vendor/ZendXml/vendor/autoload.php
index cc69a96d3..ec43ad18d 100644
--- a/vendor/ZendXml/vendor/autoload.php
+++ b/vendor/ZendXml/vendor/autoload.php
@@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
-return ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956::getLoader();
+return ComposerAutoloaderInitea88c51e6ab35b96029638db6e4797bb::getLoader();
diff --git a/vendor/ZendXml/vendor/composer/autoload_namespaces.php b/vendor/ZendXml/vendor/composer/autoload_namespaces.php
index 22f78f2ff..821332c40 100644
--- a/vendor/ZendXml/vendor/composer/autoload_namespaces.php
+++ b/vendor/ZendXml/vendor/composer/autoload_namespaces.php
@@ -6,5 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
- 'ZendXml' => array($baseDir . '/library'),
+ 'ZendXml\\' => array($baseDir . '/library'),
);
diff --git a/vendor/ZendXml/vendor/composer/autoload_psr4.php b/vendor/ZendXml/vendor/composer/autoload_psr4.php
index b265c64a2..9c321972e 100644
--- a/vendor/ZendXml/vendor/composer/autoload_psr4.php
+++ b/vendor/ZendXml/vendor/composer/autoload_psr4.php
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
+ 'ZendTest\\Xml\\' => array($baseDir . '/tests/ZendXmlTest'),
);
diff --git a/vendor/ZendXml/vendor/composer/autoload_real.php b/vendor/ZendXml/vendor/composer/autoload_real.php
index d33fba17e..b881772be 100644
--- a/vendor/ZendXml/vendor/composer/autoload_real.php
+++ b/vendor/ZendXml/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956
+class ComposerAutoloaderInitea88c51e6ab35b96029638db6e4797bb
{
private static $loader;
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInitea88c51e6ab35b96029638db6e4797bb', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
- spl_autoload_unregister(array('ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInitea88c51e6ab35b96029638db6e4797bb', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@@ -44,7 +44,7 @@ class ComposerAutoloaderInit44f71f876fa818738e1bb91ba3f97956
}
}
-function composerRequire44f71f876fa818738e1bb91ba3f97956($file)
+function composerRequireea88c51e6ab35b96029638db6e4797bb($file)
{
require $file;
}
--
cgit v1.2.3