Apakah mungkin untuk mencegah injeksi SQL di Node.js (sebaiknya dengan modul) dengan cara yang sama seperti PHP telah Mempersiapkan Pernyataan yang melindunginya.
Jika ya, bagaimana caranya? Jika tidak, apa saja contoh yang mungkin mengabaikan kode yang saya berikan (lihat di bawah).
Beberapa Konteks:
Saya membuat aplikasi web dengan back-end stack yang terdiri dari Node.js + MySql menggunakan modul node-mysql . Dari perspektif kegunaan, modul besar, tetapi belum diimplementasikan sesuatu yang mirip dengan PHP Laporan Disiapkan (meskipun aku sadar itu adalah pada todo ).
Dari pemahaman saya, implementasi PHP dari pernyataan yang disiapkan, antara lain, sangat membantu dalam pencegahan injeksi SQL. Saya khawatir, bagaimanapun, bahwa aplikasi node.js saya mungkin terbuka untuk serangan serupa, bahkan dengan string yang keluar disediakan secara default (seperti pada potongan kode di bawah).
node-mysql tampaknya menjadi konektor mysql paling populer untuk node.js, jadi saya bertanya-tanya apa yang mungkin dilakukan orang lain (jika ada) untuk memperhitungkan masalah ini - atau apakah itu bahkan masalah dengan node.js untuk memulai (tidak yakin bagaimana ini tidak terjadi, karena input sisi pengguna / klien terlibat).
Haruskah saya beralih ke node-mysql-native untuk saat ini, karena ini menyediakan pernyataan yang sudah disiapkan? Saya ragu-ragu untuk melakukan ini, karena tampaknya tidak seaktif node-mysql (meskipun itu mungkin berarti sudah selesai).
Berikut adalah potongan kode registrasi pengguna, yang menggunakan modul pembersih , bersama dengan sintaks seperti pernyataan node-mysql yang disiapkan (yang, seperti yang saya sebutkan di atas, melakukan pelolosan karakter), untuk mencegah skrip lintas situs dan injeksi sql, masing-masing:
// Prevent xss
var clean_user = sanitizer.sanitize(username);
// assume password is hashed already
var post = {Username: clean_user, Password: hash};
// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
function(err, results)
{
// Can a Sql injection happen here?
});
sumber
Perpustakaan memiliki bagian di readme tentang melarikan diri. Ini Javascript-native, jadi saya tidak menyarankan beralih ke node-mysql-native . Dokumentasi menyatakan pedoman untuk melarikan diri ini:
Edit: node-mysql-native juga merupakan solusi Javascript murni.
true
/false
stringYYYY-mm-dd HH:ii:ss
stringX'0fa5'
['a', 'b']
berubah menjadi'a', 'b'
[['a', 'b'], ['c', 'd']]
berubah menjadi('a', 'b'), ('c', 'd')
key = 'val'
pasangan. Objek bersarang dilemparkan ke string.undefined
/null
diubah menjadiNULL
NaN
AkuInfinity
dibiarkan apa adanya. MySQL tidak mendukung ini, dan mencoba memasukkannya sebagai nilai akan memicu kesalahan MySQL sampai mereka menerapkan dukungan.Ini memungkinkan Anda melakukan hal-hal seperti ini:
var userId = 5; var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) { //query.sql returns SELECT * FROM users WHERE id = '5' });
Dan juga ini:
var post = {id: 1, title: 'Hello MySQL'}; var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) { //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL' });
Selain dari fungsi tersebut, Anda juga dapat menggunakan fungsi escape:
connection.escape(query); mysql.escape(query);
Untuk menghindari pengenal kueri:
mysql.escapeId(identifier);
Dan sebagai tanggapan atas komentar Anda tentang pernyataan yang disiapkan:
Laporan siap berada di todo daftar untuk konektor ini, tetapi modul ini setidaknya memungkinkan Anda untuk menentukan format kustom yang bisa sangat mirip dengan pernyataan siap. Berikut contoh dari readme:
connection.config.queryFormat = function (query, values) { if (!values) return query; return query.replace(/\:(\w+)/g, function (txt, key) { if (values.hasOwnProperty(key)) { return this.escape(values[key]); } return txt; }.bind(this)); };
Ini mengubah format kueri koneksi sehingga Anda bisa menggunakan kueri seperti ini:
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" }); //equivalent to connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");
sumber
Saya menyadari ini adalah posting yang lebih lama tetapi tampaknya jawaban tidak pernah ditandai jadi saya akan membuang ini ke sana.
Berkenaan dengan pengujian apakah modul yang Anda gunakan aman atau tidak, ada beberapa rute yang dapat Anda ambil. Saya akan membahas pro / kontra masing-masing sehingga Anda dapat membuat keputusan yang lebih tepat.
Saat ini tidak ada kerentanan apa pun untuk modul yang Anda gunakan, namun hal ini sering kali dapat menyebabkan rasa aman yang salah karena kemungkinan besar ada kerentanan yang saat ini mengeksploitasi paket modul / perangkat lunak yang Anda gunakan dan Anda tidak akan diberi tahu masalah sampai vendor menerapkan perbaikan / tambalan.
Untuk terus mengetahui kerentanan, Anda harus mengikuti milis, forum, IRC & diskusi terkait peretasan lainnya. PRO: Anda sering kali menyadari potensi masalah dalam perpustakaan sebelum vendor diberi tahu atau telah mengeluarkan perbaikan / tambalan untuk memperbaiki kemungkinan serangan pada perangkat lunak mereka. CON: Ini bisa sangat memakan waktu dan sumber daya. Jika Anda melakukan rute ini, bot menggunakan umpan RSS, penguraian log (log obrolan IRC) dan atau scrapper web menggunakan frasa kunci (dalam hal ini node-mysql-native) dan pemberitahuan dapat membantu mengurangi waktu yang dihabiskan untuk mengontrol sumber daya ini.
Buat fuzzer, gunakan fuzzer atau kerangka kerja kerentanan lainnya seperti metasploit , sqlMap , dll. Untuk membantu menguji masalah yang mungkin tidak dicari oleh vendor. PRO: Ini dapat terbukti menjadi metode yang pasti untuk memastikan ke tingkat yang dapat diterima apakah modul / perangkat lunak yang Anda terapkan aman untuk akses publik atau tidak. CON: Ini juga menjadi memakan waktu dan mahal. Masalah lain akan berasal dari kesalahan positif serta tinjauan tidak berpendidikan dari hasil di mana masalah berada tetapi tidak diperhatikan.
Benar-benar keamanan, dan keamanan aplikasi secara umum bisa sangat memakan waktu dan sumber daya. Satu hal yang akan selalu digunakan manajer adalah formula untuk menentukan efektivitas biaya (tenaga kerja, sumber daya, waktu, gaji, dll) dari melakukan dua opsi di atas.
Bagaimanapun, saya menyadari ini bukanlah jawaban 'ya' atau 'tidak' yang mungkin diharapkan tetapi saya tidak berpikir ada yang bisa memberikannya kepada Anda sampai mereka melakukan analisis perangkat lunak yang dimaksud.
sumber
Saya tahu bahwa pertanyaan ini sudah lama tetapi bagi siapa pun yang tertarik, Mysql-native sudah ketinggalan zaman sehingga menjadi MySQL2 yang merupakan modul baru yang dibuat dengan bantuan tim modul MySQL asli. Modul ini memiliki lebih banyak fitur dan saya pikir itu memiliki apa yang Anda inginkan karena telah menyiapkan pernyataan (dengan menggunakan.execute ()) seperti di PHP untuk keamanan lebih.
Ini juga sangat aktif (perubahan terakhir adalah dari 2-1 hari) Saya tidak mencobanya sebelumnya tetapi saya pikir itu yang Anda inginkan dan banyak lagi.
sumber
Cara termudah adalah menangani semua interaksi database Anda dalam modulnya sendiri yang Anda ekspor ke rute Anda. Jika rute Anda tidak memiliki konteks database, maka SQL tetap tidak dapat menyentuhnya.
sumber