Artikel ini terutamanya memperkenalkan kaedah memanggil perintah sistem dengan selamat dalam Node.js (untuk mengelak daripada menyuntik kelemahan keselamatan secara amnya menerangkan isu keselamatan yang mungkin timbul semasa menyambungkan rentetan boleh merujuk kepadanya.
Dalam artikel ini, kita akan belajar cara menggunakan Node.js dengan betul untuk memanggil arahan sistem untuk mengelakkan kelemahan suntikan baris arahan biasa.
Kaedah yang sering kami gunakan untuk memanggil arahan ialah child_process.exec yang paling mudah. Ia mempunyai corak penggunaan yang sangat mudah dengan menghantar perintah rentetan, dan menghantar ralat atau hasil pemprosesan perintah kembali ke fungsi panggil balik.
Berikut ialah contoh yang sangat tipikal untuk memanggil arahan sistem melalui child_process.exec.
child_process.exec('ls', function (err, data) { console.log(data); });
Walau bagaimanapun, apakah yang berlaku apabila anda perlu menambah beberapa parameter yang dimasukkan pengguna pada perintah yang anda panggil? Penyelesaian yang jelas adalah untuk menggabungkan input pengguna secara langsung dengan arahan anda. Walau bagaimanapun, pengalaman bertahun-tahun saya memberitahu saya: apabila anda menghantar rentetan yang disambungkan dari satu sistem ke sistem yang lain, sesuatu akan berlaku satu hari nanti.
var path = "user input"; child_process.exec('ls -l ' + path, function (err, data) { console.log(data); });
Mengapa terdapat masalah dengan rentetan sambungan?
Nah, kerana di bawah enjin child_process.exec, "/bin/sh" akan dipanggil dan dilaksanakan. bukannya program sasaran. Perintah yang dihantar hanya dihantar ke proses '/bin/sh' baharu untuk melaksanakan shell Nama child_process.exec agak mengelirukan - ini adalah penterjemah bash, bukan memulakan program. Ini bermakna, Semua aksara shell boleh mempunyai akibat yang memusnahkan jika parameter yang dimasukkan pengguna dilaksanakan secara langsung
[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l user input"], [/* 16 vars */]
Contohnya, penyerang boleh menggunakan koma bertitik ";" untuk menamatkan perintah dan memulakan perintah baharu, mereka boleh menggunakan tanda balik atau $ () untuk menjalankan subperintah. laksanakan perintah lain dalam persekitaran shell, dan tidak akan menjalankan perintah tambahan
Mari kami gunakan execFile Ubah suai contoh sebelumnya dengan spawn untuk melihat cara panggilan sistem berbeza dan mengapa ia tidak terdedah kepada suntikan arahan. Panggilan sistem
proses_anak.spawn
sangat serupa dengan contoh menggunakan penggantian spawn bagi panggilan sistemberjalan
🎜>Apabila menggunakan spawn atau execfile, matlamatnya adalah untuk melaksanakan hanya satu arahan (parameter Ini bermakna pengguna tidak boleh menjalankan arahan yang disuntik kerana /bin/ls tidak tahu cara mengendalikan backtick atau paip). . Apa yang /bin/bash akan lakukan ialah mentafsirkan parameter perintah tersebut Ia sama dengan menggunakan jika anda sudah biasa dengannya tetapi dengan kaveat: Menggunakan spawn atau execFile tidak selalunya selamat. menjalankan /bin/mencari dan menghantar parameter input pengguna masih boleh menyebabkan sistem terjejas Perintah find mempunyai beberapa pilihan yang membenarkan membaca/menulis fail sewenang-wenangnya 🎜>Jadi, berikut ialah beberapa garis panduan untuk menjalankan perintah sistem dalam Node.js :
var child_process = require('child_process'); var path = "." child_process.execFile('/bin/ls', ['-l', path], function (err, result) { console.log(result) });
Jika anda mesti membenarkan pengguna memasukkan parameter, rujuk parameter perintah secara meluas untuk menentukan pilihan yang selamat dan buat senarai putih
[pid 25565] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]
Tutorial video Node.js!