java web项目,如何检验XML中的参数是否合法,避免出现xxe漏洞?
/**
* 解析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 的文件内容如下:
<!DOCTYPE a[<!ENTITY b SYSTEM "c:\123.txt">]>
&b;
login
<![CDATA[SUCCESS]]>
<![CDATA[OK]]>
<![CDATA[wx8775cbf90e1544d5]]>
<![CDATA[1406957502]]>
<![CDATA[RyXFitfwAY0iqotC]]>
<![CDATA[B60953438AB16569220DC885E15F8E39]]>
<![CDATA[SUCCESS]]>
<![CDATA[wx05104307622483a7349606c80845112418]]>
<![CDATA[APP]]>
可以试试过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC。
比如 xmlStr = xmlStr.replace("DOCTYPE", "").replace("SYSTEM", "").replace("ENTITY", "").replace("PUBLIC", "");
return xmlStr;
可以参考https://blog.csdn.net/golddaniu/article/details/80928537,亲测可用
转自微信:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; // catching unsupported features
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
try {
// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
// Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
// Disable external DTDs as well
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
// And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then
// ensure the entity settings are disabled (as shown above) and beware that SSRF attacks
// (http://cwe.mitre.org/data/definitions/918.html) and denial
// of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
// remaining parser logic
} 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.");
}
catch (SAXException e) {
// On Apache, this should be thrown when disallowing DOCTYPE
logger.warning("A DOCTYPE was passed into the XML document");
}
catch (IOException e) {
// XXE that points to a file that doesn't exist
logger.error("IOException occurred, XXE may still possible: " + e.getMessage());
}
DocumentBuilder safebuilder = dbf.newDocumentBuilder();