微信支付XXE漏洞修复

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 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; ++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;
}

从代码中可以看出,已经对外部实体侵入作了相应的防御

好了,我是张星,欢迎加入博主技术交流群,Java博客党①群 : 313145288,Java博客党②群:526601468

你可能感兴趣的:(java)