Overview
responsemsg() 方法将处理未经验证的 XML 输入。此调用可能允许攻击者将任意元素或属性注入 XML 文档的正文中,导致 Denial of Service 或泄漏敏感信息。XML Injection 之所以不同于 XML External Entity (XXE) Injection,是因为攻击者通常会控制插入到 XML 文档中部或末尾的输入。
Details
XML injection 会在以下情况中出现:
1. 数据从一个不可信赖的数据源进入程序。
2.数据写入到 XML 文档或解析为 XML。 在这种情况下,XML 将传递到 simplexml_load_string()。 应用程序通常使用 XML 来存储数据或发送消息。当 XML 用于存储数据时,XML 文档通常会像数据库一样进行处理,而且可能会包含敏感信息。XML 消息通常在 web 服务中使用,也可用于传输敏感信息。XML 消息甚至还可用于发送身份验证凭据。
如果攻击者能够写入原始 XML,则可以更改 XML 文档和消息的语义。危害最轻的情况下,攻击者可能会插入无关的标签,导致 XML 解析器抛出异常。XML injection 更为严重的情况下,攻击者可以添加 XML 元素,更改身份验证凭据或修改 XML 电子商务数据库中的价格。还有一些情况,XML injection 可以导致 cross-site scripting 或 dynamic code evaluation。
示例 1: 假设攻击者能够控制下列 XML 中的 shoes。
<order> <price>100.00</price>
<item>shoes</item>
</order>
现在假设,在后端 Web 服务请求中包含该 XML,用于订购一双鞋。假设攻击者可以修改请求,并将 shoes 替换成
shoes</item><price>1.00</price><item>shoes。
新的 XML 如下所示:
<order>
<price>100.00</price>
<item>shoes</item>
<price>1.00</price>
<item>shoes</item>
</order>
当使用 XML 解析器时,第二个 <price> 标签中的值将会覆盖第一个 <price> 标签中的值。这样,攻击者就可以只花 1 美元购买一双价值 100 美元的鞋。 如果攻击者控制了已解析 XML 文档的前部或全部内容,则可能会发生这种攻击的一种更严重的形式,称为 XML External Entity (XXE) Injection。
示例 2:下面是一些易受 XXE 攻击的代码: 假定攻击者能控制以下代码的输入 XML: ... <?php $goodXML = $_GET["key"]; $doc = simplexml_load_string($goodXml); echo $doc->testing; ?> ... 现在假设攻击者将以下 XML 传递到Example 2 中的代码: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/boot.ini" >]><foo>&xxe;</foo> 在处理此 XML 时,将使用系统 boot.ini 文件的内容填充 <foo> 元素的内容。攻击者可能会利用返回到客户端的 XML 元素来窃取数据或获取有关网络资源是否存在的信息。
Recommendations
在将用户提供的数据写入 XML 时,请遵循以下准则:
1.不要使用从用户输入派生的名称创建标签或属性。
2.写入到 XML 之前,先对用户输入进行 XML 实体编码。
3. 将用户输入包含在 CDATA 标签中。 当将用户提供的数据写入 XML 或解析未经验证的 XML 时,为了缓解 XML External Entity (XXE) Injection,您可以使用以下选项:
1.通过所用的 XML 解析器禁用实体扩展。
libxml_disable_entity_loader(true);
or
$dom->resolveExternals=false;
2.写入到 XML 之前,先对用户输入进行 XML 实体编码。
3. 如果需要实体扩展,则应:
a. 对输入进行验证,以确保扩展实体没有问题并允许使用。
b. 限制该解析器在加载 XML 时可以执行的功能:
$doc = XMLReader::xml($badXml,'UTF-8',LIBXML_NONET);