Veracode扫描检出CWE 611 XXE漏洞,修复代码致测试用例失败求解决
问题
我们的应用经Veracode静态扫描检测出两处CWE 611 XXE漏洞,当前使用DocumentBuilderFactory进行Java XML解析,代码如下:
final DocumentBuilder builder = factory.newDocumentBuilder(); final StringReader sr = new StringReader(this.responseXml); final InputSource is = new InputSource(sr); // SAST Vulnerability fix 611 - Improper Restriction of XML External Entity Reference //factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); //JRS - Causing an error at runtime //factory.setFeature("http://xml.org/sax/features/external-general-entities", false); //JRS - Causing an error at runtime //factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //JRS - Causing an error at runtime final Document document = builder.parse(is);// new File(argv[0]) );
启用注释中的修复代码后,测试用例失败,出现空指针异常,无法得到预期输出。已参考OWASP的XML外部实体防护cheat sheet,问题仍未解决,寻求解决建议。
解决方案建议
- 调整代码执行顺序:当前代码先创建
DocumentBuilder再设置工厂特性,完全无效。必须先对DocumentBuilderFactory设置所有防护特性,再调用newDocumentBuilder()创建解析器。正确顺序如下:// 先设置所有防护特性 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); // 再创建DocumentBuilder final DocumentBuilder builder = factory.newDocumentBuilder(); final StringReader sr = new StringReader(this.responseXml); final InputSource is = new InputSource(sr); final Document document = builder.parse(is); - 排查XML文档中的DOCTYPE声明:如果启用
disallow-doctype-decl后报错,说明responseXml中包含DOCTYPE声明。可根据业务需求选择两种处理方式:- 若业务不需要DOCTYPE,解析前直接移除XML中的DOCTYPE内容;
- 若必须保留DOCTYPE,改用更宽松的防护策略:不启用
disallow-doctype-decl,但禁用外部实体加载,并设置空实体解析器避免读取外部资源: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); // 设置空实体解析器 final DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader("")));
- 处理空指针异常:空指针通常因解析后的Document或节点为null导致。启用防护后XML解析行为变化,可能使原本可解析的节点无法读取,需检查:
- XML文档结构是否符合预期,是否因DOCTYPE被禁用丢失实体定义;
- 代码中获取节点的逻辑是否做了null判断,比如调用
getNodeValue()前确认节点不为null;
- 兼容不同XML解析器:不同JDK版本或第三方XML解析器(如Xerces)对特性支持有差异,可添加异常捕获确保兼容性:
try { factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); } catch (ParserConfigurationException | IllegalArgumentException e) { // 特性不支持时降级处理 factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); }
内容的提问来源于stack exchange,提问作者kajal Surve
相关产品推荐
相关产品推荐

