1.场景还原
近日,微信发来警告通知,告知平台微信支付可能存在XXE(外部实体注入漏洞),笔者根据微信官方技术文档及时修复了该漏洞,分享出来希望能够对大伙有所帮助
2.原因分析
所谓的外部实体注入漏洞,主要是在xml转map的时候处理不得当造成的,所以接下来的修复工作主要在xml解析类中下功夫
3.实现方案
①原有的解析类
@SuppressWarnings({ "unused", "rawtypes", "unchecked" }) public static Map parseXmlToList2(String xml) { Map retMap = new HashMap(); try { StringReader read = new StringReader(xml); // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入 InputSource source = new InputSource(read); // 创建一个新的SAXBuilder SAXBuilder sb = new SAXBuilder(); // 通过输入源构造一个Document Document doc = sb.build(source); Element root = (Element) doc.getRootElement();// 指向根节点 List<Element> es = root.getChildren(); if (es != null && es.size() != 0) { for (Element element : es) { retMap.put(element.getName(), element.getValue()); } } } catch (Exception e) { e.printStackTrace(); } return retMap; }
②修复后的解析类
@SuppressWarnings({ "unused", "rawtypes", "unchecked" }) public static Map parseXmlToList2(String strXML) throws Exception { Map data = new HashMap<>(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); String FEATURE = null; try { FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; documentBuilderFactory.setFeature(FEATURE, true); FEATURE = "http://xml.org/sax/features/external-general-entities"; documentBuilderFactory.setFeature(FEATURE, false); FEATURE = "http://xml.org/sax/features/external-parameter-entities"; documentBuilderFactory.setFeature(FEATURE, false); FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd"; documentBuilderFactory.setFeature(FEATURE, false); documentBuilderFactory.setXIncludeAware(false); documentBuilderFactory.setExpandEntityReferences(false); } catch (ParserConfigurationException e) { log.error("ParserConfigurationException was thrown. The feature '" + FEATURE + "' is probably not supported by your XML processor."); } DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder(); InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); org.w3c.dom.Document doc = documentBuilder.parse(stream); doc.getDocumentElement().normalize(); NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int idx=0; idx<nodeList.getLength(); ++idx) { Node node = nodeList.item(idx); if (node.getNodeType() == Node.ELEMENT_NODE) { org.w3c.dom.Element element = (org.w3c.dom.Element) node; data.put(element.getNodeName(), element.getTextContent()); } } try { stream.close(); } catch (Exception ex) { } return data; }
从代码中可以看出,已经对外部实体侵入作了相应的防御
转载出处: https://blog.csdn.net/zhangxing52077/article/details/80932730