修复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.map.MapUtil;
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.Reader;

View File

@ -10,26 +10,22 @@
* 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.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
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.IoUtil;
import org.dromara.hutool.core.io.file.FileUtil;
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.MapUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.text.escape.EscapeUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.dromara.hutool.core.util.CharsetUtil;
import org.w3c.dom.*;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -39,16 +35,8 @@ import org.xml.sax.helpers.DefaultHandler;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
@ -56,20 +44,8 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
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;
import java.io.*;
import java.util.*;
/**
* XML工具类<br>
@ -309,6 +285,16 @@ public class XmlUtil {
factory = SAXParserFactory.newInstance();
factory.setValidating(false);
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.从解析工厂获取解析器
final SAXParser parse;
@ -323,8 +309,15 @@ public class XmlUtil {
// 3.得到解读器
reader = parse.getXMLReader();
// 防止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);
// 不包含外部参数实体或外部DTD子集
reader.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
reader.setContentHandler(contentHandler);
reader.parse(source);
} catch (final ParserConfigurationException | SAXException e) {
@ -654,6 +647,7 @@ public class XmlUtil {
} else {
factory = DocumentBuilderFactory.newInstance();
}
// 默认打开NamespaceAwaregetElementsByTagNameNS可以使用命名空间
factory.setNamespaceAware(namespaceAware);
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;
import lombok.Data;
import org.dromara.hutool.core.xml.XmlUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

View File

@ -12,6 +12,7 @@
package org.dromara.hutool.core.util;
import lombok.Data;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.collection.ListUtil;
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.map.MapBuilder;
import org.dromara.hutool.core.map.MapUtil;
import lombok.Data;
import org.dromara.hutool.core.util.XmlUtil;
import org.dromara.hutool.core.xml.XmlUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
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.text.StrUtil;
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.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.escape.EscapeUtil;
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.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.util.CharsetUtil;
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.Request;
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.util.CharsetUtil;
import org.dromara.hutool.core.util.XmlUtil;
import org.dromara.hutool.core.xml.XmlUtil;
/**
* SOAP相关工具类

View File

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

View File

@ -1,7 +1,7 @@
package org.dromara.hutool.json;
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.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;