Является ли JSON Hijacking все еще проблемой в современных браузерах?

Я использую Backbone.js и веб-сервер Tornado. Стандартное поведение для приема данных коллекции в 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 Hijacking по-прежнему актуальными в современных браузерах?

(Примечание: Извините за возможный дубликат: возможно ли сделать "JSON hijacking" в современном браузере? Но поскольку принятый ответ, похоже, не отвечает на вопрос - я подумал, что пришло время снова спросить его и получить более ясные объяснения.)

Ответы

Ответ 1

Нет, невозможно получить значения, переданные конструкторам [] или {} в Firefox 21, Chrome 27 или IE 10. Здесь небольшая тестовая страница, основанная на основных атаках, описанных в http://www.thespanner.co.uk/2011/05/30/json-hijacking/:

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