summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-11-24 12:23:38 +0100
committerBernhard Posselt <dev@bernhard-posselt.com>2014-11-24 12:23:38 +0100
commit886647d1caf7181e947a2e771600d1addfaf53ac (patch)
tree8f821a5baa0837eaa34ebb2a180357440867bf1b
parent7025965caaa5eef6f7e6c0e0df89eff453691367 (diff)
update zendxml
-rw-r--r--articleenhancer/globalarticleenhancer.php7
-rw-r--r--articleenhancer/xpatharticleenhancer.php20
-rw-r--r--vendor/ZendXml/.gitignore5
-rw-r--r--vendor/ZendXml/.travis.yml29
-rw-r--r--vendor/ZendXml/README.md50
-rw-r--r--vendor/ZendXml/composer.json11
-rw-r--r--vendor/ZendXml/library/ZendXml/Exception/InvalidArgumentException.php4
-rw-r--r--vendor/ZendXml/library/ZendXml/Exception/RuntimeException.php4
-rw-r--r--vendor/ZendXml/library/ZendXml/Security.php51
-rw-r--r--vendor/ZendXml/tests/Bootstrap.php92
-rw-r--r--vendor/ZendXml/tests/ZendXmlTest/SecurityTest.php152
-rwxr-xr-xvendor/ZendXml/tests/phpunit.xml.dist27
-rw-r--r--vendor/ZendXml/vendor/autoload.php2
-rw-r--r--vendor/ZendXml/vendor/composer/autoload_namespaces.php2
-rw-r--r--vendor/ZendXml/vendor/composer/autoload_psr4.php1
-rw-r--r--vendor/ZendXml/vendor/composer/autoload_real.php8
16 files changed, 423 insertions, 42 deletions
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 <p> tags
$body = '<div>' . $item->getBody() . '</div>';
- 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 = '<div>' . $xml . '</div>';
- return @$dom->loadHTML($xml, LIBXML_NONET | LIBXML_HTML_NODEFDTD
- | LIBXML_HTML_NOIMPLIED);
- });
+ if($xmlString === '') {
+ return false;
+ }
+
+ $xmlString = '<div>' . $xmlString . '</div>';
+ $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 = <<<XML
+<?xml version="1.0"?>
+<results>
+ <result>test</result>
+</results>
+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();
@@ -111,6 +102,40 @@ class Security
}
/**
+ * 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
*
* @param string $file
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 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @package Zend
+ */
+
+/**
+ * Set error reporting to the level to which Zend Framework code must comply.
+ */
+error_reporting( E_ALL | E_STRICT );
+
+if (class_exists('PHPUnit_Runner_Version', true)) {
+ $phpUnitVersion = PHPUnit_Runner_Version::id();
+ if ('@package_version@' !== $phpUnitVersion && version_compare($phpUnitVersion, '3.7.0', '<')) {
+ echo 'This version of PHPUnit (' .
+ PHPUnit_Runner_Version::id() .
+ ') is not supported for ZendXml unit tests - use v 3.7.0 or higher.'
+ . PHP_EOL
+ ;
+ exit(1);
+ }
+ unset($phpUnitVersion);
+}
+
+/**
+ * Setup autoloading
+ */
+// Try to use Composer autoloader
+if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
+ include_once __DIR__ . '/../vendor/autoload.php';
+}
+// ... or use a simple SPL autoloader
+else{
+
+ // update include path
+ set_include_path(implode(PATH_SEPARATOR, array(
+ __DIR__.'/../src',
+ __DIR__,
+ get_include_path()
+ )));
+
+ /**
+ * @link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md#example-implementation
+ */
+ spl_autoload_register(function ($className) {
+ $className = ltrim($className, '\\');
+ $fileName = '';
+ $namespace = '';
+ if ($lastNsPos = strrpos($className, '\\')) {
+ $namespace = substr($className, 0, $lastNsPos);
+ $className = substr($className, $lastNsPos + 1);
+ $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
+ }
+ $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
+ require $fileName;
+ });
+
+}
+
+/**
+ * Code coverage option
+ */
+if (defined('TESTS_GENERATE_REPORT') && TESTS_GENERATE_REPORT === true) {
+ $codeCoverageFilter = new PHP_CodeCoverage_Filter();
+
+ $lastArg = end($_SERVER['argv']);
+ if (is_dir($zfCoreTests . '/' . $lastArg)) {
+ $codeCoverageFilter->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 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @link http://github.com/zendframework/zf2 for the canonical source repository
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+namespace ZendTest\Xml;
+
+use ZendXml\Security as XmlSecurity;
+use ZendXml\Exception;
+use DOMDocument;
+use SimpleXMLElement;
+
+class SecurityTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException ZendXml\Exception\RuntimeException
+ */
+ public function testScanForXEE()
+ {
+ $xml = <<<XML
+<?xml version="1.0"?>
+<!DOCTYPE results [<!ENTITY harmless "completely harmless">]>
+<results>
+ <result>This result is &harmless;</result>
+</results>
+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 = <<<XML
+<?xml version="1.0"?>
+<!DOCTYPE root
+[
+<!ENTITY foo SYSTEM "file://$file">
+]>
+<results>
+ <result>&foo;</result>
+</results>
+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 = <<<HTML
+<p>a simple test</p>
+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 = <<<XML
+<foo>test</bar>
+XML;
+
+ $result = XmlSecurity::scan($xml);
+ $this->assertFalse($result);
+ }
+
+ public function testScanInvalidXmlDom()
+ {
+ $xml = <<<XML
+<foo>test</bar>
+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 = <<<XML
+<?xml version="1.0"?>
+<!DOCTYPE results [
+<!ELEMENT results (result+)>
+<!ELEMENT result (#PCDATA)>
+]>
+<results>
+ <result>test</result>
+</results>
+XML;
+
+ $dom = new DOMDocument('1.0');
+ $result = XmlSecurity::scan($xml, $dom);
+ $this->assertTrue($result instanceof DOMDocument);
+ $this->assertTrue($result->validate());
+ }
+
+ protected function getXml()
+ {
+ return <<<XML
+<?xml version="1.0"?>
+<results>
+ <result>test</result>
+</results>
+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 @@
+<phpunit bootstrap="./Bootstrap.php" colors="true">
+ <testsuites>
+ <testsuite name="ZendXml Test Suite">
+ <directory>./ZendXmlTest</directory>
+ <exclude>./ZendXmlTest/TestAsset</exclude>
+ </testsuite>
+ </testsuites>
+
+ <groups>
+ <exclude>
+ </exclude>
+ </groups>
+
+ <listeners>
+ </listeners>
+
+ <filter>
+ <blacklist>
+ <directory suffix=".php">./ZendXmlTest</directory>
+ <directory>../vendor</directory>
+ </blacklist>
+ </filter>
+
+ <php>
+ </php>
+
+</phpunit>
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_re