Является ли угон JSON все еще проблемой в современных браузерах?
Я использую костяк.JS и веб-сервер Tornado. Стандартным поведением для получения данных сбора в магистрали является отправка в виде массива 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 все еще проблемой сегодня в современных браузерах?
(Примечание: извините за возможный дубликат: можно ли сделать "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>
он переопределяет
window.Array
и добавляет сеттер вObject.prototype.foo
и тесты инициализации массивов и объекты через короткие и длинные формы.The ES4 spec в разделе 1.5 "требует глобальной, стандартной привязки объекта и массив, который будет использоваться для строительства новых объектов для объекта, так и массива инициализаторы" и отмечает в реализации прецедента, что "Интернет Эксплорер 6, Опера 9.20 и Safari 3 не уважают местные или международные rebindings объекта и массив, но использовать исходный объект и различными конструкторами."Это сохраняется в в ES5, раздел 11.1.4.
Аллен Вирфс-объяснил Брок что ES5 также указывает, что инициализация объекта не должна вызывать сеттеры, так как он использует DefineOwnProperty. MDN: работа с объектами отмечает ,что " начиная с JavaScript 1.8.1, сеттеры больше не вызываются при настройке свойств в инициализаторах объектов и массивов."Это было адресовано в V8 выпуск 1015.