flawopen.com/SQL Injection di Ruby/ActiveRecord where()
Apakah interpolasi string di Rails where() aman?
Bayangkan SQL sebagai formulir dengan instruksi tetap dan kotak kosong untuk nilai. Parameter terikat hanya mengisi kotak; interpolasi Ruby menyisipkan teks permintaan ke instruksi sebelum Rails dapat memisahkan keduanya. Pertahankan struktur SQL dan kirim nilai yang tidak tepercaya sebagai parameter.
User.where(
"id = #{params[:id]}"
)
User.where(id: params[:id])
# or, for more complex conditions:
User.where("id = ?", params[:id])
Mengapa interpolasi mengubah kueri
Ruby mengevaluasi #{...} sebelum Active Record menerima kondisi. Contohnya, where("id = #{params[:id]}") memberikan string SQL yang sudah digabung kepada Rails; masukan permintaan kemudian dapat mengubah predikat. Active Record mendokumentasikan pola perakitan string ini sebagai tidak aman. Gunakan hash untuk kondisi kesetaraan, rentang, atau subset yang didukung, atau placeholder ? untuk predikat lain. Placeholder mengikat nilai, bukan identifier atau kata kunci SQL; pertahankan struktur kueri atau pilih identifier dari allowlist yang ketat.
Cara memeriksa basis kode
rg -n 'where\s*\(' app/Pertanyaan umum
Tidak. Kondisi hash Rails mendukung kesetaraan, rentang, dan subset (IN). Untuk predikat lain, gunakan kondisi SQL tetap dengan nilai terikat, misalnya where("price > ?", amount). Binding melindungi nilai; ini tidak mengamankan nama tabel/kolom dinamis atau fragmen SQL.