微信支付XXE漏洞
阿新 • • 發佈:2018-12-17
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