修复CVE-2023-3276漏洞,XmlUtil.readBySax问题

This commit is contained in:
Looly 2023-06-16 20:23:13 +08:00
parent 638a058b20
commit f901c9419d
11 changed files with 55 additions and 42 deletions

View File

@ -17,7 +17,7 @@ import org.dromara.hutool.core.convert.ConvertException;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;

View File

@ -10,26 +10,22 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.core.util; package org.dromara.hutool.core.xml;
import org.dromara.hutool.core.bean.BeanUtil; import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.map.BiMap; import org.dromara.hutool.core.map.BiMap;
import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.escape.EscapeUtil; import org.dromara.hutool.core.text.escape.EscapeUtil;
import org.w3c.dom.Document; import org.dromara.hutool.core.util.CharsetUtil;
import org.w3c.dom.Element; import org.w3c.dom.*;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ContentHandler; import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -39,16 +35,8 @@ import org.xml.sax.helpers.DefaultHandler;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.*;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
@ -56,20 +44,8 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import java.beans.XMLEncoder; import java.beans.XMLEncoder;
import java.io.BufferedInputStream; import java.io.*;
import java.io.BufferedWriter; import java.util.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/** /**
* XML工具类<br> * XML工具类<br>
@ -309,6 +285,16 @@ public class XmlUtil {
factory = SAXParserFactory.newInstance(); factory = SAXParserFactory.newInstance();
factory.setValidating(false); factory.setValidating(false);
factory.setNamespaceAware(namespaceAware); factory.setNamespaceAware(namespaceAware);
// https://blog.spoock.com/2018/10/23/java-xxe/
try{
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (final Exception ignore){
// ignore
}
} }
// 2.从解析工厂获取解析器 // 2.从解析工厂获取解析器
final SAXParser parse; final SAXParser parse;
@ -323,8 +309,15 @@ public class XmlUtil {
// 3.得到解读器 // 3.得到解读器
reader = parse.getXMLReader(); reader = parse.getXMLReader();
// 防止XEE攻击https://www.jianshu.com/p/1a857905b22c // 防止XEE攻击https://www.jianshu.com/p/1a857905b22c
// https://blog.spoock.com/2018/10/23/java-xxe/
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// 忽略外部DTD
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);
// 不包括外部一般实体
reader.setFeature("http://xml.org/sax/features/external-general-entities",false); reader.setFeature("http://xml.org/sax/features/external-general-entities",false);
// 不包含外部参数实体或外部DTD子集
reader.setFeature("http://xml.org/sax/features/external-parameter-entities",false); reader.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
reader.setContentHandler(contentHandler); reader.setContentHandler(contentHandler);
reader.parse(source); reader.parse(source);
} catch (final ParserConfigurationException | SAXException e) { } catch (final ParserConfigurationException | SAXException e) {
@ -654,6 +647,7 @@ public class XmlUtil {
} else { } else {
factory = DocumentBuilderFactory.newInstance(); factory = DocumentBuilderFactory.newInstance();
} }
// 默认打开NamespaceAwaregetElementsByTagNameNS可以使用命名空间 // 默认打开NamespaceAwaregetElementsByTagNameNS可以使用命名空间
factory.setNamespaceAware(namespaceAware); factory.setNamespaceAware(namespaceAware);
return disableXXE(factory); return disableXXE(factory);

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* XML相关工具封装
*
* @author looly
* @since 6.0.0
*/
package org.dromara.hutool.core.xml;

View File

@ -13,6 +13,7 @@
package org.dromara.hutool.core.util; package org.dromara.hutool.core.util;
import lombok.Data; import lombok.Data;
import org.dromara.hutool.core.xml.XmlUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -12,6 +12,7 @@
package org.dromara.hutool.core.util; package org.dromara.hutool.core.util;
import lombok.Data;
import org.dromara.hutool.core.bean.BeanUtil; import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.collection.set.SetUtil; import org.dromara.hutool.core.collection.set.SetUtil;
@ -19,8 +20,7 @@ import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.map.MapBuilder; import org.dromara.hutool.core.map.MapBuilder;
import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapUtil;
import lombok.Data; import org.dromara.hutool.core.xml.XmlUtil;
import org.dromara.hutool.core.util.XmlUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -17,7 +17,7 @@ import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;

View File

@ -17,7 +17,7 @@ import org.dromara.hutool.core.regex.ReUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.escape.EscapeUtil; import org.dromara.hutool.core.text.escape.EscapeUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;

View File

@ -19,7 +19,7 @@ import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.split.SplitUtil; import org.dromara.hutool.core.text.split.SplitUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
import org.dromara.hutool.http.client.HeaderOperation; import org.dromara.hutool.http.client.HeaderOperation;
import org.dromara.hutool.http.client.Request; import org.dromara.hutool.http.client.Request;
import org.dromara.hutool.http.client.Response; import org.dromara.hutool.http.client.Response;

View File

@ -22,7 +22,7 @@ import javax.xml.soap.SOAPMessage;
import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
/** /**
* SOAP相关工具类 * SOAP相关工具类

View File

@ -13,8 +13,7 @@
package org.dromara.hutool.json; package org.dromara.hutool.json;
import lombok.Data; import lombok.Data;
import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.xml.XmlUtil;
import org.dromara.hutool.core.util.XmlUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -1,7 +1,7 @@
package org.dromara.hutool.json; package org.dromara.hutool.json;
import org.dromara.hutool.core.io.resource.ResourceUtil; import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.util.XmlUtil; import org.dromara.hutool.core.xml.XmlUtil;
import org.dromara.hutool.json.xml.JSONXMLSerializer; import org.dromara.hutool.json.xml.JSONXMLSerializer;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;