小编典典

为什么人们会放像“throw 1;”这样的代码?"和"for(;;);" 在json响应前面?

all

Google 像这样返回 json:

throw 1; <dont be evil> { foo: bar}

Facebook 的 ajax 有这样的 json:

for(;;); {"error":0,"errorSummary": ""}
  • 为什么他们会放置会停止执行并使 json 无效的代码?
  • 如果它无效并且如果您尝试评估它会崩溃,他们如何解析它?
  • 他们是否只是将其从字符串中删除(似乎很昂贵)?
  • 这有什么安全优势吗?

作为出于安全目的的回应:

如果刮板在另一个域上,他们将不得不使用script标签来获取数据,因为 XHR
不能跨域工作。即使没有for(;;);攻击者如何获取数据?它没有分配给变量,所以它不会因为没有对它的引用而被垃圾收集吗?

基本上要跨域获取数据,他们必须这样做

<script src="http://target.com/json.js"></script>

但即使没有预先设置崩溃脚本,攻击者也无法使用任何 Json
数据,除非将其分配给您可以全局访问的变量(在这些情况下不是)。崩溃代码实际上什么也没做,因为即使没有它,他们也必须使用服务器端脚本来使用他们网站上的数据。


阅读 76

收藏
2022-06-10

共1个答案

小编典典

即使没有for(;;);攻击者如何获取数据?

攻击基于改变内置类型的行为,特别是Object通过Array改变它们的构造函数或它的prototype. 然后,当目标 JSON
使用{...}or[...]构造时,它们将成为攻击者自己的这些对象的版本,具有潜在的意外行为。

例如,您可以将 setter-property 破解到Object中,这将背叛写在对象字面量中的值:

Object.prototype.__defineSetter__('x', function(x) {
    alert('Ha! I steal '+x);
});

然后,当 a<script>指向使用该属性名称的某个 JSON 时:

{"x": "hello"}

该值"hello"将被泄露。

数组和对象字面量导致 setter 被调用的方式是有争议的。Firefox 在 3.5
版中删除了该行为,以应对对知名网站的公开攻击。然而,在撰写本文时,Safari (4) 和 Chrome (5) 仍然容易受到此攻击。

现在所有浏览器都不允许的另一种攻击是重新定义构造函数:

Array= function() {
    alert('I steal '+this);
};

[1, 2, 3]

而目前,IE8 的属性实现(基于 ECMAScript
第五版标准和Object.defineProperty)目前不适用于Object.prototypeArray.prototype

但是,除了保护过去的浏览器之外,JavaScript 的扩展可能会在未来导致更多类似类型的潜在泄漏,在这种情况下,chaff 也应该防止这些泄漏。

2022-06-10