Java XML XXE 底层防御

2022-09-13 17:48:04 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

JavaXML相关API

是由JAXP定义了相关的XML的通用接口,常见包括DOM/SAX/STAX/XPATH 的标准API

Javax.xml.parsers -> DOM/SAX

Javax.xml.stream -> STAX

Javax.xml.xpath -> XPATH

Javax.xml.bind -> JAXB

javax.xml.ws -> WS

XML解析在JDK中有两个项目

JAXWS 项目

openJDK的子项目,目录在 http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/该项目编译进jar/lib/rt.jar

主要包含 JAXB/WSweb service

如何加载哪个解析器

1. 查找jaxb.properties中定义javax.xml.bind.context.factory

2. SPI机制查找有没有实现: META-INF/services/javax.xml.ws.spi.Provider

3. 内部实现:com.sun.xml.internal.bind.v2.ContextFactory(JAXB)、com.sun.xml.internal.ws.spi.ProviderImpl(WS)

JAXP 项目

openJDK的子项目,目录在http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp/该项目编译进jar/lib/rt.jar

主要包含DOM/SAX/STAX/XPATH

如何确定加载哪个解析器

JAXP

1. 校验系统参数

2. 校验JRE/lib/jaxp.properties的参数

3. SPI检查 META-INF/service/ 参数

4. 使用默认实现

DOM查找javax.xml.parsers.DocumentBuilderFactory,默认com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl

SAX查找javax.xml.parsers.SAXParserFactor默认com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl

STAX查找:javax.xml.stream.XMLInputFactory、javax.xml.stream.XMLOutputFactory默认com.sun.xml.internal.stream.XMLInputFactoryImpl、com.sun.xml.internal.stream.XMLOutputFactoryImpl

XPATH查找:javax.xml.xpath.XPathFactory默认com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl

除了WebService 大部分都使用JAXP的API

由于考虑到使用场景和第三方库非常多,我们可以分别对JAXP 和 JAXWS进行分别防御

如何防御XXE

常见JAXP 的XXE防御

我们会在获取解析器的时候设置参数:

.setFeature(“http://apache.org/xml/features/disallow-doctype-decl“,true);

.setFeature(“http://xml.org/sax/features/external-general-entities“,false)

.setFeature(“http://xml.org/sax/features/external-parameter-entities“,false);

但这种防御依赖不同的第三方组件,需要对第三方组件的不同使用方式进行设置

底层XXE防御

通过前面的介绍,我们可以通过自定义设置DocumentBuilderFactory,SAXParserFactor,XMLInputFactory,XMLOutputFactory,XPathFactory

代码语言:javascript复制
SecureSAXParserFactoryImpl.java
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl;
public class SecureSAXParserFactoryImplextends SAXParserFactoryImpl{
   private static Map<String,String> securityConfig = new HashMap<String,String>();
   static {
       securityConfig.put("SAXParserFactory.disallow-doctype-decl", "http://apache.org/xml/features/disallow-doctype-decl");
   }
   public void consolidatedSafety()throws SAXNotRecognizedException, SAXNotSupportedException,ParserConfigurationException{
       for(String key:securityConfig.keySet()){
           setFeature(securityConfig.get(key),Boolean.parseBoolean(System.getProperty(key)));
       }
   }
   public SecureSAXParserFactoryImpl() throwsSAXNotRecognizedException, SAXNotSupportedException,ParserConfigurationException{
       consolidatedSafety();
   }
}

1. 设置运行环境参数、JRE/lib/jaxp.properties、META-INF/service/ 参数 (由你的项目决定) 为SecureSAXParserFactoryImpl

2. 通过环境变量/配置文件设置feature是否打开 -DSAXParserFactory.disallow-doctype-decl=true这样的好处是不在关心开源组件,直接使用底层的JAXP, JAXWS 的控制安全调用

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/162507.html原文链接:https://javaforall.cn

0 人点赞