Security.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Xml
  17. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /**
  22. * @category Zend
  23. * @package Zend_Xml_SecurityScan
  24. * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
  25. * @license http://framework.zend.com/license/new-bsd New BSD License
  26. */
  27. class Zend_Xml_Security
  28. {
  29. /**
  30. * Scan XML string for potential XXE and XEE attacks
  31. *
  32. * @param string $xml
  33. * @param DomDocument $dom
  34. * @throws Zend_Xml_Exception
  35. * @return SimpleXMLElement|DomDocument|boolean
  36. */
  37. public static function scan($xml, DOMDocument $dom = null)
  38. {
  39. if (null === $dom) {
  40. $simpleXml = true;
  41. $dom = new DOMDocument();
  42. }
  43. // Disable entity load
  44. $loadEntities = libxml_disable_entity_loader(true);
  45. $useInternalXmlErrors = libxml_use_internal_errors(true);
  46. if (!$dom->loadXml($xml)) {
  47. // Entity load to previous setting
  48. libxml_disable_entity_loader($loadEntities);
  49. libxml_use_internal_errors($useInternalXmlErrors);
  50. return false;
  51. }
  52. // Scan for potential XEE attacks using Entity
  53. foreach ($dom->childNodes as $child) {
  54. if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
  55. if ($child->entities->length > 0) {
  56. require_once 'Exception.php';
  57. throw new Zend_Xml_Exception(
  58. 'Detected use of ENTITY_NODE in XML, disabled to prevent XEE attacks'
  59. );
  60. }
  61. }
  62. }
  63. // Entity load to previous setting
  64. libxml_disable_entity_loader($loadEntities);
  65. libxml_use_internal_errors($useInternalXmlErrors);
  66. if (isset($simpleXml)) {
  67. $result = simplexml_import_dom($dom);
  68. if (!$result instanceof SimpleXMLElement) {
  69. return false;
  70. }
  71. return $result;
  72. }
  73. return $dom;
  74. }
  75. /**
  76. * Scan XML file for potential XXE/XEE attacks
  77. *
  78. * @param string $file
  79. * @param DOMDocument $dom
  80. * @throws Zend_Xml_Exception
  81. * @return SimpleXMLElement|DomDocument
  82. */
  83. public static function scanFile($file, DOMDocument $dom = null)
  84. {
  85. if (!file_exists($file)) {
  86. require_once 'Exception.php';
  87. throw new Zend_Xml_Exception(
  88. "The file $file specified doesn't exist"
  89. );
  90. }
  91. return self::scan(file_get_contents($file), $dom);
  92. }
  93. }