更进一步
VMware 提供培训和认证,助力你快速提升。
了解更多更新:这是无 HTML 的 XSS:使用 AngularJS 的客户端模板注入的总结。以前引文在文档中间,很难找到。总结的目的是介绍漏洞和修复方法,而不涉及所有细微之处,并非声称是我的作品。
AngularJS 是一个流行的 JavaScript 框架,它允许在双花括号内嵌入表达式。例如,表达式 1+2={{1+2}}
将渲染为 1+2=3
。
这意味着如果服务器回显了包含双花括号的用户输入,用户可以使用 Angular 表达式执行 XSS 攻击。
让我们来看一个安全地进行 HTML 编码用户输入的页面。在下面的示例中,我们使用 Thymeleaf 对用户输入进行 HTML 编码,然后将属性 username
输出到页面 div 的文本中。
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>AngularJS - Escaping the Expression Sandbox</title>
</head>
<body>
<div th:text="${username}"></div>
</body>
</html>
如果 username 是 <script>alert('Rob')</script>
,输出可能如下所示
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>AngularJS - Escaping the Expression Sandbox</title>
</head>
<body>
<div><script>alert('Rob')</script></div>
</body>
</html>
你会注意到输出已经正确地进行了 HTML 编码。这意味着我们的应用程序目前是安全的,免受 XSS 攻击。
我们的应用程序目前能够抵御 XSS 攻击。让我们更新应用程序以使用 AngularJS
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Angular Expression - safe</title>
<script src="angular-1.4.8.min.js"></script>
</head>
<body ng-app>
<div th:text="${username}"></div>
</body>
</html>
你会注意到两个变化
angular-1.4.8.min.js
的引入ng-app
我们的应用程序现在容易受到 XSS 攻击,但我们如何利用它呢?最重要的线索应该来自我们对 Angular 表达式的介绍。如果 username 是 1+2={{1+2}}
会发生什么?结果将是
<html>
<head>
<title>Angular Expression - safe</title>
<script src="angular-1.4.8.min.js"></script>
</head>
<body ng-app="">
<div>1+2={{1+2}}</div>
</body>
</html>
Angular 将更新 DOM 为
<html>
<head>
<title>Angular Expression - safe</title>
<script src="angular-1.4.8.min.js"></script>
</head>
<body ng-app="">
<div>1+2=3</div>
</body>
</html>
我们可以尝试使用 {{alert('Rob')}}
作为 username,但这会被表达式沙箱 (Expression Sandboxing) 阻止。此时你可能认为我们是安全的。然而,尽管出现在文档的安全部分,但表达式沙箱并非旨在提供安全性。
更具体地说,文档关于混合客户端和服务器端模板的描述如下:
一般来说,我们不建议这样做,因为它可能产生意想不到的 XSS 向量。
最终,这意味着如果你允许用户输入在服务器端的模板中渲染,应用程序就容易受到 XSS 攻击。让我们来看一个具体的例子。
如果我们的 payload 被沙箱限制了,我们如何提供有效的 XSS 攻击?如果我们的 username 是
{{
'a'.constructor.prototype.charAt=[].join;
eval('x=1} } };alert(1)//');
}}
通过覆盖原生函数 charAt
,我们可以绕过 Angular 的表达式沙箱,并执行 alert(1)
。有关攻击工作原理的完整详细信息,请参阅无 HTML 的 XSS:使用 AngularJS 的客户端模板注入。
注意:此 payload 针对 Chrome 和 AngularJS 1.4.8。已知在其他浏览器中无效。
允许服务器将用户输入回显到 Angular 模板中会使你的应用程序面临 XSS 攻击。更一般地,你不应混合服务器端渲染用户输入和客户端模板。你可以在 rwinch/angularjs-escaping-expression-sandbox 找到此博客文章的示例代码。