流行的 Javascript 框架 (Angularjs) 中的漏洞

信息安全 javascript 沙盒 angularjs
2021-08-19 00:13:06

我发现了一个错误,可以让您逃脱 AngularJS 模板沙箱。Angular 是一种基于胡子的模板语言。它允许您将评估的表达式放入您的 html 中。例如,{{1+1}} 在 2 处呈现

沙盒使用户无法在表达式中从 Angular 内部访问窗口/构造函数。例如,您不能这样做 {{{}.constructor = ...}}。这是因为如果站点还保存用户输入的模板,这些操作被认为是不安全的。它将站点向 XSS 开放。

翻阅源码,我发现有一个检查 obj === {}.constructor 可以绕过。

基本上,它归结为绕过这个:

if (obj) {
    if (obj === (0).constructor || obj === (false).constructor || obj ===     ''.constructor ||
      obj === {}.constructor || obj === [].constructor || obj ===     Function.constructor) {
      throw $parseMinErr('isecaf',
      'Assigning to a constructor is disallowed! Expression: {0}',      fullExpression);
    }
}

通过将构造函数调用隐藏在另一个对象(对象文字或数组文字)中,我能够通过这些检查。

作为文字对象:

{{x = {'y':''.constructor.prototype}; x['y'].charAt=[].join;$eval('x=alert(`Evaluated Object Literal`)');}}

或者作为一个数组:

{{x = [''.constructor.prototype]; x[0].charAt=[].join; $eval('x=alert(`Evaluated Array`)');}}

如何最好地改进上述检查以使这些案例失败?

我尝试将 obj === {}.constructor 检查更改为 instanceof ,这使得检查工作,但我认为它可能会引入自己的安全问题。我想提交一个拉取请求,但我希望那里的其他安全研究人员可以为对话做出贡献,以使沙箱尽可能强大。

这是我发布到 Angular 项目以供参考的问题: https ://github.com/angular/angular.js/issues/14939

以下是相关资料​​:http ://blog.portswigger.net/2016/01/xss-without-html-client-side-template.html

这是一个 jsFiddle:https ://jsfiddle.net/ianhickey/5sb665we/

1个回答

Angular 用户:停止保存未消毒的用户输入

我对自己的问题的答案有复杂的感觉。从 Angular 1.6 版开始,Angular 团队决定完全移除沙箱。在构建 Angular 应用程序时,沙盒(虽然并不完美)为用户提供了一些肤浅的保护,防止他们有自己的选择。沙盒真的很不错,而且越来越好。但沙盒也从未打算成为安全边界。它在那里试图帮助执行干净的设计原则。

随着沙箱的消失,Angular 用户将被迫考虑保存不受信任、未经清理的用户输入的安全隐患。我个人认为这是一件好事。当且仅当人们意识到进行升级时,它可能会引发他们之前忽略的更广泛的安全问题。希望这篇文章有助于在人们搜索“angular 1.6 security”时产生一些认识。

这个问题的答案是 Angular 从 1.6 开始删除了沙箱,以解决用户将沙箱用作一种从未打算使用的安全机制的事实。

Angular Sandbox Removal 博客文章