Google 像这样返回 json:
throw 1; <dont be evil> { foo: bar}
Facebook 的 ajax 有这样的 json:
for(;;); {"error":0,"errorSummary": ""}
作为出于安全目的的回应:
如果刮板在另一个域上,他们将不得不使用script标签来获取数据,因为 XHR 不能跨域工作。即使没有for(;;);攻击者如何获取数据?它没有分配给变量,所以它不会因为没有对它的引用而被垃圾收集吗?
script
for(;;);
基本上要跨域获取数据,他们必须这样做
<script src="http://target.com/json.js"></script>
但即使没有预先设置崩溃脚本,攻击者也无法使用任何 Json 数据,除非将其分配给您可以全局访问的变量(在这些情况下不是)。崩溃代码实际上什么也没做,因为即使没有它,他们也必须使用服务器端脚本来使用他们网站上的数据。
即使没有for(;;);攻击者如何获取数据?
攻击基于改变内置类型的行为,特别是Object通过Array改变它们的构造函数或它的prototype. 然后,当目标 JSON 使用{...}or[...]构造时,它们将成为攻击者自己的这些对象的版本,具有潜在的意外行为。
Object
Array
prototype
{...}
[...]
例如,您可以将 setter-property 破解到Object中,这将背叛写在对象字面量中的值:
Object.prototype.__defineSetter__('x', function(x) { alert('Ha! I steal '+x); });
然后,当 a<script>指向使用该属性名称的某个 JSON 时:
<script>
{"x": "hello"}
该值"hello"将被泄露。
"hello"
数组和对象字面量导致 setter 被调用的方式是有争议的。Firefox 在 3.5 版中删除了该行为,以应对对知名网站的公开攻击。然而,在撰写本文时,Safari (4) 和 Chrome (5) 仍然容易受到此攻击。
现在所有浏览器都不允许的另一种攻击是重新定义构造函数:
Array= function() { alert('I steal '+this); }; [1, 2, 3]
而目前,IE8 的属性实现(基于 ECMAScript 第五版标准和Object.defineProperty)目前不适用于Object.prototype或Array.prototype。
Object.defineProperty
Object.prototype
Array.prototype
但是,除了保护过去的浏览器之外,JavaScript 的扩展可能会在未来导致更多类似类型的潜在泄漏,在这种情况下,chaff 也应该防止这些泄漏。