Apakah ketergantungan pada permintaan parametrized satu-satunya cara untuk melindungi terhadap injeksi SQL?

13

Semua yang saya lihat pada serangan injeksi SQL tampaknya menunjukkan bahwa permintaan parametrized, terutama yang ada di prosedur tersimpan, adalah satu-satunya cara untuk melindungi terhadap serangan tersebut. Ketika saya bekerja (pada Abad Kegelapan) prosedur tersimpan dianggap sebagai praktik yang buruk, terutama karena mereka dianggap kurang dapat dipertahankan; kurang teruji; sangat berpasangan; dan mengunci sistem menjadi satu vendor; ( pertanyaan ini mencakup beberapa alasan lain).

Meskipun ketika saya sedang bekerja, proyek-proyek sebenarnya tidak menyadari kemungkinan serangan seperti itu; berbagai aturan diadopsi untuk mengamankan database terhadap berbagai macam korupsi. Aturan-aturan ini dapat diringkas sebagai:

  1. Tidak ada klien / aplikasi yang memiliki akses langsung ke tabel database.
  2. Semua akses ke semua tabel melalui tampilan (dan semua pembaruan ke tabel dasar dilakukan melalui pemicu).
  3. Semua item data memiliki domain yang ditentukan.
  4. Tidak ada item data yang boleh dibatalkan - ini memiliki implikasi yang membuat DBA menggiling gigi mereka kadang-kadang; tetapi ditegakkan.
  5. Peran dan izin ditetapkan dengan tepat - misalnya, peran terbatas untuk memberikan hanya pandangan hak untuk mengubah data.

Jadi apakah seperangkat aturan (ditegakkan) seperti ini (meskipun tidak harus set khusus ini) merupakan alternatif yang sesuai untuk pertanyaan parametrized dalam mencegah serangan injeksi SQL? Jika tidak, mengapa tidak? Bisakah suatu basis data diamankan dari serangan semacam itu dengan tindakan khusus (hanya) basis data?

EDIT

Penekanan pertanyaan sedikit berubah, mengingat respons awal yang diterima. Pertanyaan dasar tidak berubah.

EDIT2

Pendekatan mengandalkan queri paramaterized tampaknya hanya langkah periferal dalam pertahanan terhadap serangan pada sistem. Tampak bagi saya bahwa pertahanan yang lebih mendasar keduanya diinginkan, dan dapat membuat ketergantungan pada pertanyaan seperti itu tidak perlu, atau kurang kritis, bahkan untuk mempertahankan secara khusus terhadap serangan injeksi.

Pendekatan yang tersirat dalam pertanyaan saya didasarkan pada "menambah" database dan saya tidak tahu apakah itu pilihan yang layak. Penelitian lebih lanjut telah menyarankan bahwa ada pendekatan semacam itu. Saya telah menemukan sumber-sumber berikut yang menyediakan beberapa petunjuk untuk jenis pendekatan ini:

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

Fitur utama yang saya ambil dari sumber-sumber ini adalah:

  1. Kamus data yang luas, dikombinasikan dengan kamus data keamanan yang luas
  2. Generasi pemicu, kueri, dan kendala dari kamus data
  3. Minimalkan Kode dan maksimalkan data

Sementara jawaban yang saya miliki sejauh ini sangat berguna dan menunjukkan kesulitan yang timbul karena mengabaikan pertanyaan yang bersifat paramaterisasi, pada akhirnya mereka tidak menjawab pertanyaan awal saya (sekarang ditekankan dengan huruf tebal).

Chris Walton
sumber
Saya tidak membeli argumen terhadap prosedur tersimpan. Itu tidak benar.
Konrad Rudolph
Ada apa dengan persyaratan no-nulls?
Mark Canlas
2
@Konrad Rudolph - Jika Anda menulis aplikasi pada MySQL dan kemudian memutuskan untuk bermigrasi ke DB2, apakah Anda benar-benar berpikir prosedur tersimpan akan kompatibel? Begitu juga jika Anda ingin bermigrasi ke SQLLite? Juga, misalkan Anda memutakhirkan OS Anda - jika prosedur tersimpan Anda dikompilasi dalam C (yang ada dalam DB2), mereka semua mungkin perlu kompilasi ulang. Ini adalah argumen yang masuk akal - tidak absolut, tetapi masuk akal.
Matthew Flynn
@ Matius Duh. Saya sebenarnya memikirkan "pertanyaan parametris" ketika membaca itu dan berkomentar tentang hal itu. Prosedur tersimpan = seluruh cerita nother.
Konrad Rudolph

Jawaban:

25

Procs yang disimpan tidak secara otomatis melindungi dari injeksi. Bagaimana dengan ini

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

Menggunakan query parameterised akan melindungi Anda terhadap injeksi, apakah itu dalam procs atau tidak.

Craig
sumber
Terima kasih atas fokus pada kueri parameterised, bukan procs. Namun, saya bertanya apakah basis data dapat dilindungi oleh metode selain dari pertanyaan semacam itu - khususnya metode yang hanya terbatas pada lapisan basis data.
Chris Walton
1
+1 Selain itu, saya ingin menyatakan bahwa procs yang disimpan sebagian besar dianggap aman karena merupakan satu-satunya cara untuk mencegah pengguna mengakses tabel secara langsung sambil tetap mempertahankan cara untuk mengambil data. Ini adalah satu-satunya cara untuk memastikan hak berbasis baris dan berbasis kolom ketika pengguna perlu memiliki akses database langsung dengan kliennya tanpa ada apa pun di antaranya.
Falcon
2
@ Chris - Saya pikir apa yang dikatakan Craig di sini adalah bahwa Anda tidak dapat berasumsi bahwa procs sebenarnya melindungi Anda. Itu mungkin bukan jawaban yang lengkap, lebih merupakan koreksi dari asumsi dalam judul.
Jon Hopkins
@ Jon - Saya telah mengubah judul pertanyaan, dan membuat beberapa perubahan pada pertanyaan, mengingat koreksi Craig. Saya tidak menyadari asumsi yang saya buat dalam pertanyaan, sampai saya mulai menerima balasan.
Chris Walton
2
Untuk memperkuat apa yang ditulis Craig di atas, lihat databasesecurity.com/dbsec/lateral-sql-injection.pdf , "Injeksi Lateral SQL: Kelas Baru Kerentanan dalam Oracle"
Bruce Ediger
11

Jadi apakah seperangkat aturan (ditegakkan) seperti ini merupakan alternatif yang tepat untuk prosedur yang tersimpan dalam mencegah serangan injeksi SQL? Jika tidak, mengapa tidak?

Tidak, karena mereka memberikan hukuman yang cukup berat pada pengembang. Rincian per item:

1. Tidak ada klien / aplikasi memiliki akses langsung ke tabel database.

Gunakan peran. Klien seharusnya hanya dapat mengakses DB melalui peran terbatas yang hanya memiliki akses SELECT, INSERT, UPDATE, dan DELETE ke tabel tersebut (dan baris, jika mungkin) yang memerlukan akses. Jika Anda ingin memastikan bahwa tidak ada klien yang dapat mengirim spam atau menghapus semua entri, gunakan API untuk modifikasi data.

2. Semua akses ke semua tabel melalui tampilan.

Itu bisa berupa apa saja, mulai dari yang dapat diabaikan hingga biaya kinerja yang sangat besar, tergantung pada efisiensi pandangan. Kompleksitas yang tidak perlu yang memperlambat pengembangan. Gunakan peran.

3. Semua item data memiliki domain yang ditentukan.

Bisa jadi banyak pekerjaan yang harus dipertahankan, dan mungkin harus dinormalisasi menjadi tabel terpisah.

4. Tidak ada item data yang boleh dibatalkan - ini memiliki implikasi yang membuat DBA menggiling gigi mereka kadang-kadang; tetapi ditegakkan.

Itu salah sekali. Jika pengembang tidak dapat menangani NULLAnda memiliki masalah besar.

Bisakah suatu basis data diamankan dari serangan semacam itu dengan tindakan khusus (hanya) basis data?

Anda tidak perlu prosedur tersimpan, cukup gunakan kueri parametrized dengan fungsi yang lolos dari argumen, seperti pg_query_params . Tentu saja, jika basis data Anda dapat ditulisi dunia atau peran klien memiliki akses penuh ke semuanya, Anda tetap kacau. Seseorang harus datang dan menyadari apa yang klien lakukan, dan kemudian memasak klien dalam lima menit yang menghancurkan (atau lebih buruk, racun) DB Anda.

l0b0
sumber
1
Domain: en.wikipedia.org/wiki/Data_domain
Dan McGrath
+1 untuk peran. Mereka adalah kontributor utama untuk ini - saya tidak memasukkan peran dalam pertanyaan saya, tetapi mereka adalah bagian dari pengaturan - khususnya pandangan ditugaskan peran terbatas seperti yang Anda sarankan untuk klien. Poin diambil pada hit kinerja dilihat. Domain termasuk tes validasi - rentang dan panjangnya sebagian besar. Komentar Anda tentang aturan nullable data jauh lebih sopan daripada yang saya dengar tentang aturan ini. Saya tidak menyatakan secara eksplisit bahwa izin akan diatur dengan tepat meskipun ini adalah asumsi saya.
Chris Walton
6

Saya tidak yakin aturan Anda benar-benar melindungi Anda.

Masalah pertama adalah bahwa Anda menyatakan mereka ditegakkan tetapi, serta datang dengan overhead yang signifikan, saya belum pernah melihat penegakan yang sempurna.

Kedua, pembacaan saya terhadap mereka adalah bahwa aturan seperti ini mungkin membuat hal-hal lebih sulit untuk dieksploitasi tetapi mereka tidak mencegahnya. Misalnya, tidak memiliki akses langsung ke tabel tidak benar-benar berubah banyak jika tampilan memungkinkan Anda untuk mengakses data yang sama. Jika klien perlu melakukan sesuatu, sebuah tampilan perlu memfasilitasi itu dan jika sebuah tampilan memfasilitasinya, fungsi / data yang sama dapat digunakan oleh penyerang.

Ingat juga bahwa ini bukan hanya tentang memperbarui atau menghapus data. Bagian dari kerentanan dengan injeksi SQL adalah pengumpulan informasi dan untuk itu Anda tidak peduli apakah data telah dikembalikan melalui tampilan vCustomers atau tabel Pelanggan yang mendasarinya. Anda mungkin telah melindungi diri dari beberapa kelemahan tetapi tidak semua. Demikian pula jika pembaruan dapat dibuat oleh klien, bahkan jika melalui pemicu, maka SQL dapat ditulis untuk mengaktifkan pemicu dan membuat pembaruan.

(Dalam hal semua pembaruan yang dilakukan melalui pemicu saya akan mengatakan dua hal: (1) ketika saya membaca ini saya sedikit sakit di mulut saya dan (b) Anda tidak suka Prosedur Tersimpan karena mereka ' kembali "kurang dapat dipelihara; kurang dapat diuji; sangat berpasangan; dan mengunci sistem menjadi satu vendor" tetapi Anda memang menggunakan pemicu tentang hal-hal yang sama pada dasarnya dapat dikatakan.)

Yang Anda butuhkan adalah satu lubang yang memungkinkan eksekusi pernyataan SQL (dan saya tidak melihat aturan ini mencegahnya) dan penyerang masuk. Mereka mungkin menemukan database yang sangat tidak intuitif di belakangnya tetapi jika mereka memutuskan bahwa akan hanya memperlambat mereka daripada menghentikannya).

Hal lain di sini adalah Anda juga menambahkan kompleksitas dan (dan juga overhead yang menciptakan), kompleksitas cenderung mengarah pada lubang yang dapat dieksploitasi.

Saya tidak mengatakan bahwa seperangkat aturan seperti itu tidak dapat dibuat - lebih lagi mengapa Anda repot-repot? Mereka tampak lebih rumit dan kurang dapat diandalkan daripada hanya pergi dengan metode yang diterima secara luas untuk mencegah serangan semacam ini.

Jon Hopkins
sumber
+1 untuk memahami permintaan saya yang sebenarnya berdasarkan asumsi implisit, tidak sadar saya, dan untuk meresponsnya dengan tepat. Adapun mengapa orang mungkin repot - saya sedang mengerjakan proyek di mana banyak kode akan dihasilkan dari deskripsi yang relevan dari arsitektur - dan bagian dari arsitektur ini menjelaskan cara menghasilkan rutinitas akses database. Masih terbuka seperti apa bentuk rutinitas yang dihasilkan ini.
Chris Walton