* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map doXMLParse(String strxml) throws JDOMException, IOException {
//过滤关键词,防止XXE漏洞攻击
strxml = XMLUtil.filterXXE(strxml);
//
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if(null == strxml || "".equals(strxml)) {
return null;
}
Map m = new HashMap();
InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = XMLUtil.getChildrenText(children);
}
m.put(k, v);
}
//关闭流
in.close();
return m;
}
/**
* 防止 XXE漏洞 注入实体攻击
* 过滤 过滤用户提交的XML数据
* 过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。
*/
public static String filterXXE(String xmlStr){
xmlStr = xmlStr.replace("DOCTYPE", "").replace("SYSTEM", "").replace("ENTITY", "").replace("PUBLIC", "");
return xmlStr;
}
//*****************以下为测试 攻击代码***** 内部调试用**************************
// public static void main(String[] args) {
// String strxml = XMLUtil.readFileByLines("C:\\text.xml");
// try {
// XMLUtil.doXMLParse(strxml);
// } catch (JDOMException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
C:\\text.xml 的文件内容如下:
<xml>
<!DOCTYPE a[<!ENTITY b SYSTEM "c:\\123.txt">]>
<reset>
<login>&b;</login>
<secret>login</secret>
</reset>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx8775cbf90e1544d5]]></appid>
<mch_id><![CDATA[1406957502]]></mch_id>
<nonce_str><![CDATA[RyXFitfwAY0iqotC]]></nonce_str>
<sign><![CDATA[B60953438AB16569220DC885E15F8E39]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx05104307622483a7349606c80845112418]]></prepay_id>
<trade_type><![CDATA[APP]]></trade_type>
</xml>