Injeksi SQL dalam fungsi Postgres vs kueri yang disiapkan

30

Dalam Postgres, apakah query yang disiapkan dan fungsi yang didefinisikan pengguna setara sebagai mekanisme untuk menjaga terhadap injeksi SQL ?
Apakah ada kelebihan tertentu dalam satu pendekatan dibandingkan yang lain?

mickeyf_supports_Monica
sumber

Jawaban:

36

Tergantung.

Fungsi SQL

Dengan LANGUAGE sql, jawabannya umumnya ya .

Parameter yang dilewati diperlakukan sebagai nilai dan SQL-injeksi tidak mungkin - selama Anda tidak memanggil fungsi yang tidak aman dari tubuh dan meneruskan parameter.

Fungsi PL / pgSQL

Dengan LANGUAGE plpgsql, jawabannya biasanya ya .

Namun , PL / pgsql memungkinkan untuk SQL dinamis di mana parameter yang dikirimkan (atau bagian) yang bersambung ke string query dan dieksekusi dengan EXECUTE. Hal ini dapat mengkonversi input pengguna untuk kode SQL dan membuat SQL injection mungkin . Anda tidak dapat mengetahui dari luar apakah fungsi tubuh menanganinya dengan benar. Alat disediakan.

Hanya gunakan SQL dinamis di mana Anda membutuhkannya. Pernyataan SQL biasa menggunakan parameter karena nilainya aman terhadap injeksi SQL seperti fungsi SQL.

Untuk SQL dinamis , sebaiknya berikan nilai sebagai nilai dengan:

Membuat injeksi SQL tidak mungkin pada prinsipal.

Jika Anda menggabungkan nilai dalam string SQL, gunakan:

Membungkus string dalam tanda kutip tunggal dengan aman, sehingga menghindari kesalahan sintaksis dan injeksi SQL.

Parameter proses yang harus diperlakukan sebagai pengidentifikasi dalam string SQL dengan:

Lampirkan string dalam tanda kutip ganda dengan aman jika diperlukan , sehingga menghindari kesalahan sintaksis dan injeksi SQL.

Terkait:

Jangan pernah hanya membangun string dari input pengguna dan jalankan. Ini termasuk pengidentifikasi, secara langsung dilewati oleh pengguna atau diambil dari katalog sistem. Semua harus diperlakukan seperti input pengguna dan dikutip dengan aman ketika membangun SQL dinamis!

Lebih lanjut tentang implikasi kinerja dalam jawaban terkait ini:

Dasar-dasar pada SQL-injection:

Pertimbangan serupa berlaku untuk bahasa sisi server lain yang memungkinkan SQL dinamis.

Erwin Brandstetter
sumber
Jadi, dalam ringkasan: Jika 1) Saya hanya menggunakan bahasa sql, saya aman, 2) jika saya menggunakan plpgslq tetapi tidak mengeksekusi, saya aman, 3) jika saya menggunakan plpgsql dan mengeksekusi tetapi tidak ada pengidentifikasi dan% s atau% L sepantasnya saya aman, atau 4) jika saya menggunakan plpgsql dan mengeksekusi dan pengidentifikasi tetapi% I atau quote_ident yang sesuai saya aman. Benar?
mickeyf_supports_Monica
@ickeyf: Pada dasarnya ya. Plus, gunakan USINGklausa untuk meneruskan nilai EXECUTEjika memungkinkan. Anda bisa memanggil fungsi PL / pgSQL dari dalam fungsi SQL dan meneruskan parameter. Jadi, untuk benar-benar benar, Anda aman selama Anda tidak memanggil fungsi tidak aman secara langsung atau tidak langsung. Jika semua fungsi Anda dilakukan dengan benar, itu tidak dapat terjadi.
Erwin Brandstetter