CodeQL 文档

在用户控制的数据中解析 XML 外部实体

ID: java/xxe
Kind: path-problem
Security severity: 9.1
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-611
   - external/cwe/cwe-776
   - external/cwe/cwe-827
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

单击以在 CodeQL 存储库中查看查询

使用配置较弱的 XML 解析器解析不受信任的 XML 文件可能会导致 XML 外部实体 (XXE) 攻击。此类攻击使用外部实体引用来访问系统上的任意文件、执行拒绝服务或服务器端请求伪造。即使解析结果未返回给用户,带外数据检索技术也可能允许攻击者窃取敏感数据。在这种情况下,也可以执行拒绝服务。

Java 有许多 XML 解析器,其中大多数容易受到 XXE 攻击,因为它们的默认设置启用了外部实体的解析。此查询目前识别以下解析器的易受攻击 XML 解析:javax.xml.parsers.DocumentBuilderjavax.xml.stream.XMLStreamReaderorg.jdom.input.SAXBuilder/org.jdom2.input.SAXBuilderjavax.xml.parsers.SAXParserorg.dom4j.io.SAXReaderorg.xml.sax.XMLReaderjavax.xml.transform.sax.SAXSourcejavax.xml.transform.TransformerFactoryjavax.xml.transform.sax.SAXTransformerFactoryjavax.xml.validation.SchemaFactoryjavax.xml.bind.Unmarshallerjavax.xml.xpath.XPathExpression

建议

防止 XXE 攻击的最佳方法是禁用对不受信任数据中的任何文档类型声明 (DTD) 的解析。如果无法做到这一点,则应禁用对外部通用实体和外部参数实体的解析。这可以提高安全性,但代码仍有遭受拒绝服务和服务器端请求伪造攻击的风险。还可以通过设置实体扩展限制来防止拒绝服务攻击,这是最近的 JDK 和 JRE 实现中默认执行的操作。我们建议访问 OWASP 的 XML 实体预防备忘单,找到特定的 XML 解析器,并应用其中列出的缓解措施。在某些情况下,其他缓解措施可能足够,但需要手动验证,因为查询将继续将解析器标记为潜在危险。

示例

以下示例在不受信任的数据上调用 parse,该数据未在 DocumentBuilder 上安全配置,因此本质上不安全。

public void parse(Socket sock) throws Exception {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder builder = factory.newDocumentBuilder();
  builder.parse(sock.getInputStream()); //unsafe
}

在此示例中,DocumentBuilder 在禁用 DTD 的情况下创建,从而使其免受 XXE 攻击。

public void disableDTDParse(Socket sock) throws Exception {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  factory.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true);
  DocumentBuilder builder = factory.newDocumentBuilder();
  builder.parse(sock.getInputStream()); //safe
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私