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

IT技术 javascript json security browser tornado
2021-01-29 01:34:57

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

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

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

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

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

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

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

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

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

1个回答

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

( 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>

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

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

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

对 POST CSRF 是肯定的。感谢您在这里提供的所有重要信息。
2021-03-13 01:34:57
当您的陈述仅指简单地覆盖 Array 构造函数时,它是正确的。不过,微软的 IE 和 Edge 仍然容易受到 UTF-7 JSON 劫持的影响。最近对其进行了测试(今天又为了好玩),它仍然有效。
2021-03-20 01:34:57
请注意,盲 POST CSRF 仍然可以使用表单,尤其是文本/纯编码,并且需要使用令牌/随机数来击败。
2021-03-22 01:34:57
早在 2009 年,Brendan Eich 就建议浏览器不要评估用作 application/json 的脚本 ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ),这对我来说仍然是一个好主意。
2021-03-28 01:34:57
UTF-16BE 也是如此,感谢 Gareth Heyes,blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html
2021-03-29 01:34:57