• 【JAVA XXE攻击】微信支付官方回应XML外部实体注入漏洞


    官方回应连接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5

    其中明确指出了代码修改的地方。

    然后看到此文档后,我就改公司项目中代码,项目中支付时并没有涉及到XML解析,

    而是在支付后,微信回调告知支付结果时,我这边接受时需要解析XML。

        /**
         * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
         * @param strxml
         * @return
         * @throws JDOMException
         * @throws IOException
         */
        public static Map doXMLParse(String strxml) throws JDOMException, IOException {
            if(null == strxml || "".equals(strxml)) {
                return null;
            }
            
            Map m = new HashMap();
            InputStream in = HttpClientUtil.String2Inputstream(strxml);
            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);
            }

    很明显,我这个原有的代码中解析XML时,并没有“DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();”,而是 SAXBuilder builder = new SAXBuilder();

    后来发现当使用SAXBuilder时 ,可以这样处理以达到防止XXE攻击。

    /**
         * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
         * @param strxml
         * @return
         * @throws JDOMException
         * @throws IOException
         */
        public static Map doXMLParse(String strxml) throws JDOMException, IOException {
            if(null == strxml || "".equals(strxml)) {
                return null;
            }
            
            Map m = new HashMap();
            InputStream in = HttpClientUtil.String2Inputstream(strxml);
            SAXBuilder builder = new SAXBuilder();
    
            // 这是优先选择. 如果不允许DTDs (doctypes) ,几乎可以阻止所有的XML实体攻击
            String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
            builder.setFeature(FEATURE, true);
    
            FEATURE = "http://xml.org/sax/features/external-general-entities";
            builder.setFeature(FEATURE, false);
    
            FEATURE = "http://xml.org/sax/features/external-parameter-entities";
            builder.setFeature(FEATURE, false);
    
            FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
            builder.setFeature(FEATURE, false);
    
            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;
        }

    即:设置builder的feature ,

    / 这是优先选择. 如果不允许DTDs (doctypes) ,几乎可以阻止所有的XML实体攻击
            String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
            builder.setFeature(FEATURE, true);
    
            FEATURE = "http://xml.org/sax/features/external-general-entities";
            builder.setFeature(FEATURE, false);
    
            FEATURE = "http://xml.org/sax/features/external-parameter-entities";
            builder.setFeature(FEATURE, false);
    
            FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
            builder.setFeature(FEATURE, false);
    

     

  • 相关阅读:
    [Unity3D]蓝港面试题
    BZOJ 2186 SDOI2008 沙拉公主的困惑 数论
    JSONObject与JSONArray的使用
    一个int类型究竟占多少个字节
    软件开发的金字塔
    poj 1064 Cable master ,二分 精度!!!
    php实现工厂模式
    数据库索引的作用和长处缺点
    C++中使用class和structkeyword的不同
    提交时提示错误This Bundle is invalid.New apps and app updates submitted to the App Store must be built wit
  • 原文地址:https://www.cnblogs.com/hero123/p/9282753.html
Copyright © 2020-2023  润新知