Tips Mencegah SQL injection di Node.js
Meskipun Node.js membantu pengembang menjadi lebih produktif, Node.js rentan terhadap bug SQL Injection seperti bahasa pemrograman modern lainnya yang digunakan saat ini, Artikel ini menjelaskan masalah SQL Injection, implikasinya, dan cara memperbaikinya.
Contoh umum menggunakan MySQL
Bayangkan sebuah aplikasi web yang perlu memverifikasi rekening bank Anda sehingga Anda dapat mengakses dana pribadi Anda. Setelah meninjau beberapa informasi, sistem akan mengumpulkan dan menampilkan total saldo Anda sehingga Anda dapat melakukan transfer bank, pembayaran, dan lainnya.
Di balik layar, pengembang Node.js mengimplementasikan kode berikut.
connection.query("SELECT * FROM bank_accounts WHERE dob = '" + req.body.dob + "' AND bank_account = '" + req.body.account_number + "'",
function(error, results) {
}
);
Apa yang salah dengan kode ini? Yah, kecuali untuk logika validasi yang mencurigakan (apakah hari ulang tahun Anda satu-satunya elemen tambahan yang Anda butuhkan?!), kode tersebut memungkinkan input pengguna untuk melewati apa adanya. Tidak ada pelolosan atau penyaringan karakter. Bagaimana saya bisa memperbaiki SQL Injection?
Sangat mudah untuk memperbaikinya. Anda perlu mengubah kode Anda sehingga input pengguna secara otomatis lolos sebelum dijalankan. Dengan MySQL, Anda dapat menentukan variabel mana yang akan diloloskan dalam metode query() itu sendiri.
Ada dua opsi untuk memperbaikinya:
Placeholders
Anda dapat memetakan nilai dalam larik ke placeholder (tanda tanya) dalam urutan yang sama dengan yang diteruskan.
connection.query("SELECT * FROM bank_accounts WHERE dob = ? AND bank_account = ?",
[
req.body.dob,
req.body.account_number
],
function(error, results) {
}
);
Named placeholder
This is similar to the example above, but the attribute name in the object is the placeholder for the SQL query.
connection.query("SELECT * FROM bank_accounts WHERE dob = :dob AND bank_account = :account_number",
{
dob: req.body.dob,
account_number: req.body.account_number
},
function(error, results) {
}
);
Bagaimana jika saya tidak memperbaiki kode ini?
Jika Anda tidak menghindari input pengguna dengan benar, MySQL akan mengeksekusi string persis seperti yang Anda ketik. Ini berarti bahwa semua karakter, termasuk sintaks SQL, dianggap sebagai bagian dari keseluruhan query SQL.
Ini dapat menyebabkan berbagai peretasan. Ambil dua contoh: ekstraksi data dan query destruktif.
kebocoran data
Misalkan Anda memasukkan string ini di bidang formulir tanggal lahir:
1970/01/01’; --
Begini cara MySQL menafsirkannya:
SELECT * FROM bank_accounts WHERE dob = '1970/01/01'; -- ' AND bank_account = '1111987654321'
Akibatnya, hanya sebagian dari logika query yang dieksekusi. Logika SQL tambahan yang memerlukan nomor rekening_bank akan diabaikan. Dalam kasus penggunaan perbankan, ini akan memberi pengguna akses ke semua pelanggan pada hari ulang tahun mereka 1 Januari 1970.
Bahkan jika aplikasi web Anda memiliki perlindungan yang memberikan pengecualian ketika sejumlah besar baris dikembalikan, penyerang dapat menghindari solusi semacam itu hanya dengan menambahkan klausa "LIMIT" ke string serangan.
SQL Injection yang merusak
Sekarang mari kita perluas querynya sedikit. Tambahkan perintah DROP ke serangan.
1970/01/01'; DROP TABLE bank_accounts; --
Begini cara MySQL menafsirkannya:
SELECT * FROM bank_accounts WHERE dob = '1970/01/01'; DROP TABLE bank_accounts; -- ' AND bank_account = '1111987654321'
aya telah secara efektif menginstruksikan MySQL untuk menjalankan dua query, salah satunya menjatuhkan tabel bank_accounts. Jangan mengandalkan pemfilteran khusus
Anda mungkin berkata pada diri sendiri, "Saya telah menerapkan filter khusus ke input pengguna sebelum meneruskannya ke query SQL, jadi saya tidak perlu membuat perubahan lebih lanjut pada kode."
Secara umum, itu adalah saran yang berbahaya. Sangat mungkin bahwa ada pola serangan yang menurut Anda tidak dapat menyelinap melalui logika penyaringan karakter Anda. Tentu saja, menggunakan logika filter khusus dapat mempersulit penyerang untuk berhasil, tetapi itu bukan tidak mungkin. Karena beberapa perubahan kode yang ditargetkan, Anda dapat beristirahat dengan lebih nyaman di malam hari.
Dalam contoh ekstraksi data, database dan manajemen operasi tidak dapat menghentikan query yang salah format. Sederhananya, string serangan memodifikasi query SQL sehingga kriteria filter tambahan diabaikan. Ini adalah cara yang pasti untuk mengembalikan data yang salah kepada pengguna.
Ketika datang ke pertanyaan destruktif, Anda mungkin berkata pada diri sendiri, "Anda tidak diizinkan untuk menggunakan perintah DROP dalam produksi." Ini adalah perlindungan yang baik, tetapi konfigurasi produksi dapat berubah seiring waktu dalam beberapa kasus karena kesalahan. Pengamanan adalah aspek penting dari pertahanan secara mendalam, tetapi itu bukan jaminan. Mirip dengan logika pemfilteran karakter khusus, penyerang bisa sulit untuk masuk, tetapi kontrol seperti itu biasanya "pencuri" untuk mengurangi risiko sementara. Ubah kode yang mendasarinya.
Kesimpulan: Satu-satunya cara untuk mencegah SQL Injection adalah dengan memodifikasi kode.