Apakah JSON Hijacking masih menjadi masalah di browser modern?

149

Saya menggunakan Backbone.js dan server web Tornado. Perilaku standar untuk menerima data pengumpulan di Backbone adalah mengirim sebagai JSON Array.

Di sisi lain, perilaku standar Tornado adalah untuk tidak mengizinkan JSON Array karena kerentanan berikut:

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

Yang terkait adalah: http://haacked.com/archive/2009/06/25/json-hijacking.aspx

Rasanya lebih alami bagi saya untuk tidak harus membungkus JSON saya dalam suatu objek ketika itu benar-benar daftar objek.

Saya tidak dapat mereproduksi serangan ini di browser modern (yaitu Chrome, Firefox, Safari, dan IE9 saat ini). Pada saat yang sama saya tidak dapat mengkonfirmasi di mana pun bahwa browser modern telah mengatasi masalah ini.

Untuk memastikan bahwa saya tidak menyesatkan baik oleh keterampilan pemrograman yang buruk maupun keterampilan googling yang buruk:

Apakah serangan Pembajakan JSON ini masih menjadi masalah saat ini di browser modern?

(Catatan: Maaf untuk kemungkinan duplikat ke: Apakah mungkin untuk melakukan 'pembajakan JSON' di browser modern? Tetapi karena jawaban yang diterima tampaknya tidak menjawab pertanyaan - Saya pikir sudah waktunya untuk bertanya lagi dan mendapatkan beberapa penjelasan yang lebih jelas. .)

Manusia Roket
sumber
menggunakan eval? maka mungkin sebaliknya. Tidak. Jika tidak ada yang diubah atau diubah dengan cara respons backbone parse maka Anda harus aman
Deeptechtons
10
Secara umum, Anda tidak boleh mendekati keamanan web dengan asumsi bahwa seseorang akan menggunakan browser "modern".
Lukas
7
@ Lukas - Lihat komentar di bawah untuk Reid. Poin bagus secara umum - tapi saya tidak menanyakan pertanyaan keamanan umum. (Pengguna saya hanya akan dapat mengautentikasi jika mereka menggunakan browser modern sejak awal.)
Rocketman
4
@ Lukas, kadang-kadang kita harus melanjutkan dan memungkinkan kita untuk berkembang dengan pola modern (seperti REST dalam kasus ini: memperoleh data adalah operasi GET dan tidak boleh menjadi sesuatu yang lain) tanpa melindungi terhadap ancaman lama jika sekarang tampaknya hanya berlaku untuk audiens kecil. Jadi pertanyaan ini sangat berharga, untuk memungkinkan seseorang mengevaluasi apakah ia dapat mengabaikan ancaman ini atau tidak untuk kasus lamarannya. Pada titik tertentu, pengguna dengan perangkat lunak yang sangat usang cenderung memiliki jenis ancaman lain (malware) yang tidak dapat kami lindungi.
Frédéric
2
@ jpaugh, di mana Anda melihat asumsi seperti itu? Saya hanya agak berasumsi bahwa orang-orang dengan perangkat lunak yang usang seperti itu "tidak dapat melindungi". (Tentang membenarkan biaya sepatu roda saya, saya sudah terbiasa untuk menempatkan sepertiga dari harga mereka di sepatu roda karbon yang usang dalam waktu kurang dari sepertiga waktu yang dibutuhkan saya untuk memakai sepatu roda saya saat ini. Dan lagi pula, saya pikir mereka layak, asalkan Anda suka mengendarai mereka, yang merupakan kasus saya.)
Frédéric

Jawaban:

112

Tidak, tidak lagi mungkin untuk mengambil nilai yang diteruskan ke []atau {}konstruktor di Firefox 21, Chrome 27, atau IE 10. Berikut adalah halaman uji kecil, berdasarkan serangan utama yang dijelaskan dalam http://www.thespanner.co.uk / 2011/05/30 / json-pembajakan / :

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

Mengganti window.Arraydan menambahkan setter keObject.prototype.foo dan menguji inisialisasi array dan objek melalui formulir pendek dan panjang.

The ES4 spesifikasi , dalam bagian 1.5, "memerlukan global, binding standar Obyek dan Array yang akan digunakan untuk membangun objek baru untuk objek dan array yang initializers" dan catatan dalam Implementasi Preseden bahwa "Internet Explorer 6, Opera 9.20, dan Safari 3 do tidak menghormati penghindaran Object dan Array lokal atau global, tetapi gunakan konstruktor Object and Array yang asli. " Ini dipertahankan dalam ES5, bagian 11.1.4 .

Allen Wirfs-Brock menjelaskan bahwa ES5 juga menentukan bahwa inisialisasi objek tidak boleh memicu setter, karena menggunakan DefineOwnProperty. MDN: Bekerja dengan Objects mencatat bahwa "Mulai dalam JavaScript 1.8.1, setter tidak lagi dipanggil saat menyetel properti di inisialisasi objek dan array." Ini telah diatasi dalam edisi V8 1015 .

jpaugh
sumber
28
Kembali pada tahun 2009 Brendan Eich menyarankan agar browser tidak mengevaluasi skrip yang berfungsi sebagai application / json ( bugzilla.mozilla.org/show_bug.cgi?id=376957#c75 ), yang sepertinya masih merupakan ide bagus bagi saya.
2
Perhatikan bahwa POST CSRF buta masih dimungkinkan menggunakan formulir, terutama dengan pengkodean teks / polos, dan perlu dikalahkan menggunakan token / nonces.
1
Ya untuk POST CSRF. Terima kasih atas semua info hebat Anda di sini.
Rocketman
5
Pernyataan Anda benar ketika merujuk hanya menimpa konstruktor Array. Microsoft IE dan Edge masih rentan terhadap pembajakan JSF UTF-7. Mengujinya baru-baru ini (dan untuk bersenang-senang hari ini lagi), dan masih berfungsi.
user857990
2
UTF-16BE juga, terima kasih kepada Gareth Heyes, blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html
eel ghEEz