我发现了一个错误,可以让您逃脱 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/