【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); 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM