WebLogic 12C自定义DocumentBuilderFactoryImpl防XXE攻击遇阻求助
我来帮你分析下为什么你的两种配置在WebLogic 12c里都没生效,以及对应的解决办法:
一、自定义DocumentBuilderFactoryImpl失效的原因与修复
WebLogic 12c自带了一套XML解析器实现,它不会自动识别并使用你自定义的工厂类,而且你的代码里重写的几个关键方法是空实现,这也会导致功能异常。
修复步骤:
强制指定自定义工厂类
在WebLogic的启动脚本(比如startWebLogic.sh/startWebLogic.cmd)中添加系统属性,告诉JVM使用你的自定义工厂:-Djavax.xml.parsers.DocumentBuilderFactory=com.your.package.CustomDocumentBuilderFactoryImpl记得替换成你实际的包路径。
修复自定义类的方法实现
你重写的setAttribute、getAttribute、setFeature、getFeature都是空实现,这会破坏原有解析器的功能,应该调用父类的实现,同时可以在setFeature中强制锁定安全特性:import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; public class CustomDocumentBuilderFactoryImpl extends DocumentBuilderFactoryImpl { @Override public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { // 先设置所有安全特性 super.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); super.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); super.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true); super.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); super.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); super.setXIncludeAware(false); super.setExpandEntityReferences(false); return super.newDocumentBuilder(); } @Override public void setAttribute(String name, Object value) throws IllegalArgumentException { super.setAttribute(name, value); // 调用父类实现 } @Override public Object getAttribute(String name) throws IllegalArgumentException { return super.getAttribute(name); // 调用父类实现 } @Override public void setFeature(String name, boolean value) throws ParserConfigurationException { // 强制锁定安全特性,防止被外部修改 if ("http://apache.org/xml/features/disallow-doctype-decl".equals(name) || "http://javax.xml.XMLConstants/feature/secure-processing".equals(name)) { value = true; } if ("http://apache.org/xml/features/nonvalidating/load-dtd-grammar".equals(name) || "http://apache.org/xml/features/nonvalidating/load-external-dtd".equals(name)) { value = false; } super.setFeature(name, value); } @Override public boolean getFeature(String name) throws ParserConfigurationException { // 确保安全特性返回正确值 if ("http://apache.org/xml/features/disallow-doctype-decl".equals(name) || "http://javax.xml.XMLConstants/feature/secure-processing".equals(name)) { return true; } if ("http://apache.org/xml/features/nonvalidating/load-dtd-grammar".equals(name) || "http://apache.org/xml/features/nonvalidating/load-external-dtd".equals(name)) { return false; } return super.getFeature(name); } }确保类被正确加载
把自定义类打包到应用的WEB-INF/classes或者WEB-INF/lib中,或者放到WebLogic域的domain/lib目录下,确保WebLogic能加载到这个类。
二、Spring-Security的StaticBasicParserPool在WebLogic中失效的解决办法
WebLogic的类加载机制会优先使用自带的XML解析相关类,覆盖了你Spring配置的解析池。解决这个问题需要调整WebLogic的类加载优先级:
配置weblogic.xml
在你的应用的WEB-INF/weblogic.xml中添加以下配置,让WebLogic优先加载应用中的XML解析和OpenSAML相关类:
<weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd"> <wls:container-descriptor> <wls:prefer-application-packages> <wls:package-name>org.opensaml.*</wls:package-name> <wls:package-name>javax.xml.parsers.*</wls:package-name> <wls:package-name>org.xml.sax.*</wls:package-name> <wls:package-name>org.w3c.dom.*</wls:package-name> </wls:prefer-application-packages> </wls:container-descriptor> </weblogic-web-app>
这个配置会让WebLogic优先从应用的类路径加载这些包,而不是使用自带的实现,这样你的Spring配置的parserPool就能生效了。
三、更简单的全局XXE防护方案
如果你不想修改代码或应用配置,也可以通过WebLogic控制台全局开启XXE防护:
- 登录WebLogic控制台,进入Domain > Configuration > XML
- 勾选Secure XML Processing
- 设置Disallow DOCTYPE Declarations为
true - 设置Load External DTDs为
false - 保存配置并重启服务器
这个方式是全局生效的,所有部署在该域的应用都会自动使用这些安全特性,不需要单独配置。
内容的提问来源于stack exchange,提问作者SubhenduGN

