Чи JSON Викрадення все ще залишається проблемою в сучасних браузерах?


149

Я використовую Backbone.js та веб-сервер Tornado. Стандартна поведінка для отримання даних збору в Backbone - це надсилання як масив JSON.

З іншого боку, стандартна поведінка Торнадо не допускає використання масиву 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). У той же час я не зміг ніде підтвердити, що сучасні браузери вирішували ці проблеми.

Щоб переконатися, що мене не вводять в оману ні можливі погані навички програмування, ні погані навички googling:

Ці напади викрадення JSON досі залишаються проблемою в сучасних браузерах?

(Примітка. Вибачте за можливий дублікат: Чи можна робити "викрадення JSON" у сучасному браузері? Але оскільки прийнята відповідь, здається, не відповідає на питання - я подумав, що настав час задати її ще раз і отримати більш чіткі пояснення. .)


використовуючи eval? тоді можливо інакше Ні. Якщо нічого не було змінено або змінено способом реакції на магістраль, то ви повинні бути в безпеці
Deeptechtons

10
Взагалі кажучи, ніколи не слід підходити до веб-безпеки з припущенням, що хтось збирається використовувати "сучасний" браузер.
Лука

7
@Luke - Дивіться коментар Reid нижче. Велике значення в цілому - але я не задаю загального питання безпеки. (Мої користувачі зможуть підтвердити автентифікацію лише у тому випадку, якщо вони спочатку користуються сучасним браузером.)
Rocketman

4
@Luke, іноді нам доводиться рухатися далі і дозволяти нам розвиватися за допомогою сучасних моделей (наприклад, REST у цьому випадку: отримання даних - це GET-операція і не повинно бути чимось іншим) без захисту від старих загроз, якщо вони, здається, зараз застосовуються лише для невеликої аудиторії. Отож, це запитання справді цінне, щоб можна було оцінити, чи може він ігнорувати цю загрозу чи ні для своєї заявки. У якийсь момент користувачі з дуже застарілим програмним забезпеченням, ймовірно, матимуть інші види загроз (зловмисне програмне забезпечення), від яких ми не зможемо їх захистити в будь-якому випадку.
Фредерік

2
@jpaugh, де ти бачиш такі припущення? Я лише дещо припускаю, що ті люди з таким застарілим програмним забезпеченням в будь-якому випадку є "незахищеними". (Щодо виправдання вартості моїх ковзанів, я вже використовувався для того, щоб покласти третину їхньої ціни на ковзани з вуглецевими швидкостями, які зношувалися менше ніж на третину, коли потрібно, щоб я зношував свої поточні ковзани. І все одно, я думаю, що вони того варті, за умови, що ти любиш їздити на них, що є моїм випадком.)
Фредерік

Відповіді:


112

Ні, більше неможливо фіксувати значення, передані []або {}конструкторам у 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та додає сеттер Object.prototype.fooі тестує ініціалізацію масивів та об'єктів за допомогою коротких та довгих форм.

Специфікація ES4 у розділі 1.5 "вимагає використання глобальних, стандартних прив'язок об'єкта та масиву для побудови нових об'єктів для ініціалізаторів об'єктів та масивів" та зазначає у "Прецеденті впровадження", що "Internet Explorer 6, Opera 9.20 та Safari 3 роблять не поважайте ані локальні, ані глобальні відтворення об'єктів та масиву, але використовуйте оригінальні конструктори Object and Array. " Це зберігається в ES5, розділ 11.1.4 .

Аллен Вірфс-Брок пояснив, що ES5 також вказує, що ініціалізація об'єкта не повинна запускати сетерів, оскільки він використовує DefineOwnProperty. MDN: Робота з об’єктами зазначає, що "Починаючи з JavaScript 1.8.1, сеттери більше не викликаються при встановленні властивостей в ініціалізатори об'єктів і масивів." Це було розглянуто у V8 випуску 1015 .


28
Ще в 2009 році Брендан Ейх запропонував браузерам не оцінювати сценарії, які використовуються як application / json ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ), що все ще здається мені гарною ідеєю.

2
Зауважте, що сліпий POST CSRF все ще можливий за допомогою форм, особливо з кодуванням тексту / звичайного, і його потрібно перемогти за допомогою лексем / нікелів.

1
Так, для POST CSRF. Дякуємо за всю вашу чудову інформацію тут.
Rocketman

5
Ваше твердження правильне, коли воно стосується лише простого перезапису конструктора масиву. Мікрософт IE і Edge все ще вразливі до викрадення UTF-7 JSON. Тестували його нещодавно (і для задоволення сьогодні знову), і він все ще працює.
користувач857990

2
Також UTF-16BE, завдяки Гарету Хейсу
вугор ghEEz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.