1.PHP
1.1 SimpleXML
SimpleXML是PHP5后提供的一套简单易用的xml工具集,可以把xml转换成方便处理的对象,也可以组织生成xml数据。不过它不适用于包含namespace的xml,而且要保证xml格式完整(well-formed)。它提供了三个方法:simplexml_import_dom、simplexml_load_file、simplexml_load_string,函数名很直观地说明了函数的作用。三个函数都返回SimpleXMLElement对象,数据的读取/添加都是通过SimpleXMLElement操作.
simplexml_load_file:直接解析xml文件,如下例子:
<?php
if (file_exists('test.xml'))
{
$xml = simplexml_load_file('test.xml');
var_dump($xml);
}
else
{
exit('Error.');
}
?>
simplexml_load_string:解析xml数据,如下例子:
<?php
$xmlstring = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XML;
$xml = simplexml_load_string($xmlstring);
var_dump($xml);
?>
以上两种方法对xml的解析都是存在xxe漏洞的风险,如果要防御xxe漏洞,php提供了禁止导入外部实体的方法。
libxml_disable_entity_loader:打开或关闭外部实体导入功能,如关闭需要在解析xml之前调用该函数并将参数置为:true,如下例子:
<?php
$xmlstring = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
XML;
Libxml_disable_entity_loader(true);//禁止外部实体注入
$xml = simplexml_load_string($xmlstring);
var_dump($xml);
?>
2.java
2.1 DOM
DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作,如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
System.out.println("class name: " + dbf.getClass().getName());
// step 2:获得具体的dom解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// step3: 解析一个xml文档,获得Document对象(根结点)
Document document = db.parse(new File("candidate.xml"));
NodeList list = document.getElementsByTagName("PERSON");
防御建议1:完全禁止DTDs,这样几乎可以完全阻止所有的xml实体攻击,如下例子:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Try{
// 这是优先选择. 如果不允许DTDs (doctypes) ,几乎可以阻止所有的XML实体攻击
String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true); //设置该特征如上传xml文件包含DTDs将提示报错。
System.out.println("class name: " + dbf.getClass().getName());
// step 2:获得具体的dom解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// step3: 解析一个xml文档,获得Document对象(根结点)
Document document = db.parse(new File("candidate.xml"));
NodeList list = document.getElementsByTagName("PERSON");
}
catch (ParserConfigurationException e) {
// This should catch a failed setFeature feature
logger.info("ParserConfigurationException was thrown. The feature '" +
FEATURE +
"' is probably not supported by your XML processor.");
...
}
...
防御建议2:如不完全禁止DTDs,可单独禁止外部实体导入,如下例子:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Try{
// 如果不能完全禁用DTDs,最少采取以下措施
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and