JSON 劫持在现代浏览器中仍然是一个问题吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16289894/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:43:13  来源:igfitidea点击:

Is JSON HiHymaning still an issue in modern browsers?

javascriptjsonsecuritybrowsertornado

提问by Rocketman

I am using Backbone.js and the Tornado web server. The standard behavior for receiving collection data in Backbone is to send as a JSON Array.

我正在使用 Backbone.js 和 Tornado Web 服务器。在 Backbone 中接收集合数据的标准行为是作为 JSON 数组发送。

On the other hand, Tornado's standard behavior is to not allow JSON Array's due to the following vulnerability:

另一方面,由于以下漏洞,Tornado 的标准行为是不允许 JSON 数组:

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

A related one is: http://haacked.com/archive/2009/06/25/json-hiHymaning.aspx

一个相关的是:http: //haacked.com/archive/2009/06/25/json-hiHymaning.aspx

It feels more natural for me to not have to wrap up my JSON in an object when it really is a list of objects.

当它确实是一个对象列表时,我感觉不必将我的 JSON 包装在一个对象中更自然。

I was unable to reproduce these attacks in modern browsers (i.e. current Chrome, Firefox, Safari, and IE9). At the same time I was unable to confirm anywhere that modern browsers had addressed these issues.

我无法在现代浏览器(即当前的 Chrome、Firefox、Safari 和 IE9)中重现这些攻击。同时,我无法在任何地方确认现代浏览器已经解决了这些问题。

To ensure that I am mislead neither by any possible poor programming-skills nor poor googling-skills:

为了确保我不会被任何可能的糟糕的编程技能或糟糕的谷歌搜索技能所误导:

Are these JSON HiHymaning attacks still an issue today in modern browsers?

这些 JSON 劫持攻击今天在现代浏览器中仍然是一个问题吗?

(Note: Sorry for the possible duplicate to: Is it possible to do 'JSON hiHymaning' on modern browser?but since the accepted answer does not seem to answer the question - I thought it was time to ask it again and get some clearer explanations.)

(注意:很抱歉可能重复:Is it possible to do 'JSON hiHymaning' on modern browser?但由于接受的答案似乎没有回答这个问题 - 我想是时候再问一次并得到一些更清晰的解释了.)

采纳答案by Rocketman

No, it is no longer possible to capture values passed to the []or {}constructors in Firefox 21, Chrome 27, or IE 10. Here's a little test page, based on the main attacks described in http://www.thespanner.co.uk/2011/05/30/json-hiHymaning/:

不,在 Firefox 21、Chrome 27 或 IE 10 中无法再捕获传递给[]{}构造函数的值。这是一个小测试页面,基于http://www.thespanner.co.uk 中描述的主要攻击/2011/05/30/json-劫持/

(http://jsfiddle.net/ph3Uv/2/)

( http://jsfiddle.net/ph3Uv/2/)

var capture = function() {
    var ta = document.querySelector('textarea')
 ta.innerHTML = '';
 ta.appendChild(document.createTextNode("Captured: "+JSON.stringify(arguments)));
 return arguments;
}
var original = Array;

var toggle = document.body.querySelector('input[type="checkbox"]');
var toggleCapture = function() {
    var isOn = toggle.checked;
    window.Array = isOn ? capture : original;
    if (isOn) {
        Object.defineProperty(Object.prototype, 'foo', {set: capture});    
    } else {
        delete Object.prototype.foo;
    }
};
toggle.addEventListener('click', toggleCapture);
toggleCapture();

[].forEach.call(document.body.querySelectorAll('input[type="button"]'), function(el) {
    el.addEventListener('click', function() {
        document.querySelector('textarea').innerHTML = 'Safe.';
        eval(this.value);
    });
});
<div><label><input type="checkbox" checked="checked"> Capture</label></div>
<div><input type="button" value="[1, 2]" /> <input type="button" value="Array(1, 2);" /> <input type="button" value="{foo: 'bar'}" /> <input type="button" value="({}).foo = 'bar';" /></div>
<div><textarea></textarea></div>

It overrides window.Arrayand adds a setter to Object.prototype.fooand tests initializing arrays and objects via the short and long forms.

它通过短格式和长格式覆盖window.Array并添加一个setterObject.prototype.foo并测试初始化​​数组和对象。

The ES4 spec, in section 1.5, "requires the global, standard bindings of Object and Array to be used to construct new objects for object and array initializers" and notes in Implementation Precedent that "Internet Explorer 6, Opera 9.20, and Safari 3 do not respect either local or global rebindings of Object and Array, but use the original Object and Array constructors." This is retained in ES5, section 11.1.4.

ES4规范,在第1.5节,“需要的对象和阵列的全球性的,标准绑定到被用于构建用于对象和数组的初始化新对象”在实施先例与指出,“Internet Explorer 6中,歌剧9.20,和Safari 3执行不尊重 Object 和 Array 的局部或全局重新绑定,而是使用原始的 Object 和 Array 构造函数。” 这保留在ES5 的第 11.1.4 节中

Allen Wirfs-Brock explainedthat ES5 also specifies that object initialization should not trigger setters, as it uses DefineOwnProperty. MDN: Working with Objectsnotes that "Starting in JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers." This was addressed in V8 issue 1015.

Allen Wirfs-Brock 解释说 ES5 还指定对象初始化不应触发 setter,因为它使用了 DefineOwnProperty。MDN:使用对象指出“从 JavaScript 1.8.1 开始,在对象和数组初始值设定项中设置属性时不再调用 setter。” 这已在V8 问题 1015 中得到解决。