FlawOpen

flawopen.com/Parsing JSON/JSON.parse() vs eval()

Apakah JSON.parse() lebih aman daripada eval()?

Panduan referensi
Jawaban singkat

Bayangkan masukan sebagai catatan: JSON.parse() membaca kolom dari formulir terstruktur, sedangkan eval() menyerahkan catatan itu kepada interpreter sebagai instruksi untuk dijalankan. JSON.parse() mengikuti tata bahasa JSON dan tidak menjalankan JavaScript di dalam teks; nilai hasilnya tetap harus divalidasi sebelum digunakan.

BERBAHAYA — pola lama
// Jangan menafsirkan data yang tidak tepercaya sebagai kode sumber program.
const data = eval("(" + untrustedJson + ")");
AMAN
const data = JSON.parse(untrustedJson);
// Parse JSON sebagai data; JSON tidak valid memunculkan SyntaxError.

Mengapa pertanyaan ini muncul

Sebelum JSON.parse() tersedia luas, sebagian kode JavaScript lama menggunakan eval() untuk membaca JSON karena teks JSON bertumpang tindih dengan sintaks ekspresi JavaScript. Cara itu mengevaluasi program JavaScript, sehingga masukan yang dikendalikan penyerang dapat diperlakukan sebagai kode, bukan dibatasi pada nilai JSON. Gunakan parser JSON untuk membaca JSON.

Hal yang tidak dilindungi JSON.parse()

JSON.parse() tidak memvalidasi aturan bisnis, mengotorisasi tindakan, atau membuat nilai hasil parsing aman untuk HTML, SQL, perintah shell, maupun URL. Validasi bentuk data yang diharapkan dan gunakan pengodean keluaran sesuai konteks atau API berparameter. Jika Anda memberikan reviver, callback dari aplikasi itu berjalan selama parsing; pastikan callback tepercaya, sederhana, dan tidak menimbulkan efek samping berdasarkan nilai yang dikendalikan penyerang.

Pertanyaan umum

Bisakah JSON.parse() menjalankan kode aplikasi?

Teks JSON itu sendiri diurai sebagai data, bukan dijalankan sebagai JavaScript. Namun, jika aplikasi memberikan reviver, callback tepercaya tersebut dipanggil untuk nilai hasil parsing dan dapat menjalankan kode. Jangan biarkan data yang dikendalikan penyerang memilih atau membentuk logika callback yang dapat dieksekusi.

Apakah JSON.parse() membuat masukan aman untuk penggunaan berikutnya?

Tidak. Periksa nilai hasil parsing terhadap skema yang diharapkan aplikasi dan aturan otorisasi. Gunakan pengodean keluaran untuk HTML dan kueri berparameter untuk SQL; parsing bukan sanitasi untuk konteks tersebut.

Referensi

Lihat juga Prototype Pollution JavaScript: penyebab dan perbaikan Apakah lodash.merge() aman dari prototype pollution? Object.assign() dan Prototype Pollution: apa yang aman? Apakah JSON.parse() menyebabkan prototype pollution?