在Java应用程序中防止XXE


欢迎回到简化的AppSec!在本教程中,我们将讨论如何在Java应用程序中防止XXE。

为什么发生XXE

DTD用于定义XML文档的结构。在DTD中,您可以声明“ XML实体”。有一种特殊类型的XML实体称为“外部实体”,用于通过URL访问本地或远程内容。

例如,此DTD声明了一个名为“ file”的外部实体,该实体指向file:///secrets.txt本地文件系统上。XML解析器将&file使用的内容替换文档中的任何引用file:///secrets.txt。

XML格式

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE example [
  <!ENTITY file SYSTEM "file:///secrets.txt" >
]>
<example>&file;</example>

如果用户可以在上载中声明任意XML实体,则可以在您计算机上的任何位置声明一个外部实体。例如,此XML文件包含指向file:////etc/shadow您服务器上的外部实体。

XML格式

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE example [
  <!ENTITY file SYSTEM "file:////etc/shadow" >
]>
<example>&file;</example>

“ / etc / shadow”文件在Unix系统上存储用户名及其加密的密码。当将已解析的XML文档显示给用户时,file:////etc/shadow还将包含的内容。

XXE的影响

通过利用XML解析器,恶意用户现在可以读取服务器上的任意文件。他们可以访问和泄露本地计算机上的文件,例如系统文件,源代码,目录列表。

网络探索

除了获取系统文件之外,攻击者还可以使用XXE漏洞对本地网络发起SSRF攻击。例如,他们可以通过使用服务器上的不同端口切换外部实体的URL来启动端口扫描。使用这种技术,他们可以浏览本地网络以找到其他易受攻击的机器或服务作为目标。

XML格式

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE example [
  <!ENTITY file SYSTEM "http://10.0.0.1:80" >
]>
<example>&file;</example>

XXE还可以用于启动SSRF以读取AWS云服务实例元数据。通过访问地址169.254.169.254,攻击者可能能够检索托管云提供商的访问令牌,机密和会话令牌密钥。

XML格式

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE example [
  <!ENTITY file SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/" >
]>
<example>&file;</example>

拒绝服务 攻击者可以利用XML漏洞的另一种潜在方法是发起“拒绝服务”攻击,这是当攻击者破坏计算机从而使合法用户无法访问其服务时。

以这个XML文件为例。此DTD将实体嵌入实体中,从而使XML解析器递归解除引用,以获取根实体值“ lol”。

XML格式

<?xml version=”1.0" encoding=”UTF-8"?>
<!DOCTYPE example [
<!ELEMENT example ANY >
<!ENTITY lol “lol”>
<!ENTITY lol1 “&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;”>
<!ENTITY lol2 “&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;”>
<!ENTITY lol3 “&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;”>
<!ENTITY lol4 “&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;”>
<!ENTITY lol5 “&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;”>
<!ENTITY lol6 “&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;”>
<!ENTITY lol7 “&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;”>
<!ENTITY lol8 “&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;”>
<!ENTITY lol9 “&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;”>]>

<example>&lol9;</example>

每个“ lol9”实体将扩展为十个“ lol8”,而每个实体将变为十个“ lol7”,依此类推。最终,一个“ lol9”将扩展为十亿个“ lol”。这将使XML解析器的内存过载,从而可能导致其崩溃。

这种攻击方法称为“十亿笑声攻击”或“ XML炸弹”。有趣的是,尽管此攻击通常被归类为XXE攻击,但它不涉及任何外部实体的使用!它使用内部实体的递归处理。

在Java中防止XXE

那么如何防止XXE发生呢?防止XXE的最佳方法是限制XML解析器的功能。

由于XXE攻击需要DTD处理,因此开发人员应在其XML解析器上禁用DTD处理。如果不可能完全禁用DTD,则应禁用外部实体,参数实体和嵌入式DTD。您还可以完全禁用XML实体的扩展。如何配置XML解析器的行为将取决于您使用的XML解析器。

Java应用程序特别容易出现XXE,因为大多数Java XML解析器默认都启用了XXE的要求。为了防止Java应用程序中的XXE攻击,您需要显式禁用这些功能。

DocumentBuilderFactory

例如,对于DocumentBuilderFactory库,您可以使用此行禁止DTD。

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

如果无法完全禁用DTD,则可以禁止XML外部实体和参数实体。参数实体是XML实体,只能在DTD内的其他地方引用。它们还可以允许攻击者启动XXE。

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

您还应该禁用外部DTD,以防止攻击者托管外部DTD并在XML文档中引用它。

dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

XInclude是一种特殊的XML功能,可从标记构建单独的XML文档。它们还允许攻击者触发XXE。因此,将“ setXIncludeAware”设置为false以禁止XInclude处理。最后,设置“ setExpandEntityReferences”以防止解析器将XML实体递归扩展为XML炸弹。

dbf.setXIncludeAware(false); 
dbf.setExpandEntityReferences(false);

XMLInputFactory

对于XMLInputFactory,这些行禁用DTD和外部实体。

xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xmlInputFactory.setProperty(“javax.xml.stream.isSupportingExternalEntities”, false);

XMLReader

为了保护XMLReader免受XXE的侵害,您可以禁止DTD和外部DTD:

reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

或者禁用外部和参数实体的使用。

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

对于不同的Java XML解析器,保护解析器免受XXE攻击所需的代码有所不同。有关如何争取到更多的信息,不同的解析器访问OWASP小抄这里。

使图书馆保持最新

您不仅应该注意您的XML解析器。许多第三方库都处理XML,因此容易受到XXE攻击。验证您的依赖项不受XXE攻击的影响,然后将库更新为安全版本。

希望您在本教程中玩得开心!我肯定写得很开心。静态分析是发现应用程序中大多数漏洞的最有效方法。如果您想了解有关ShiftLeft静态分析工具NG-SAST的更多信息,请在此处访问我们。

谢谢阅读!为您开发安全软件最具挑战性的部分是什么?我很想知道。随时在Twitter @ vickieli7上进行连接。


原文链接:http://codingdict.com