zoukankan      html  css  js  c++  java
  • 【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);
    

     

  • 相关阅读:
    js 性能调试
    js 面向对象编程
    js 零碎
    如果遇到二维数组 想取某个字段的和
    昨天写支付接口时遇到支付接口返回数据接收地址,session数据丢失(或者说失效)的问题
    mysql报错: 1548-Cannot load from mysql.proc. The table is probably corrupted 解决办法
    php 时间倒计时代码 个人写法 有好的想法的欢迎贴出来分享
    linux 环境下安装mysql5.6
    关于数据库连接不上 出现错误的问题
    推荐一个不错的css3网站 可以直接调用的
  • 原文地址:https://www.cnblogs.com/hero123/p/9282753.html
Copyright © 2011-2022 走看看