Hanya melihat:
(Sumber: https://xkcd.com/327/ )
Apa yang dilakukan SQL ini:
Robert'); DROP TABLE STUDENTS; --
Saya tahu keduanya '
dan --
untuk komentar, tetapi bukankah kata itu DROP
dikomentari juga karena itu adalah bagian dari baris yang sama?
security
validation
sql-injection
Blankman
sumber
sumber
'
bukan untuk komentar . Bahkan jika itu, tidak ada ruang sebelumnya sehingga hanya dapat mengakhiri string yang mendahuluinya.Jawaban:
Itu menjatuhkan meja siswa.
Kode asli dalam program sekolah mungkin terlihat seperti
Ini adalah cara naif untuk menambahkan input teks ke dalam kueri, dan sangat buruk , seperti yang akan Anda lihat.
Setelah nilai-nilai dari nama pertama, nama tengah textbox FNMName.Text (yang
Robert'); DROP TABLE STUDENTS; --
) dan nama terakhir textbox LName.Text (sebut sajaDerper
) yang bersambung dengan sisa query, hasilnya adalah sekarang benar-benar dua pertanyaan dipisahkan oleh terminator pernyataan (titik koma). Permintaan kedua telah disuntikkan ke yang pertama. Ketika kode mengeksekusi query ini terhadap database, itu akan terlihat seperti iniyang, dalam bahasa Inggris yang sederhana, secara kasar diterjemahkan ke dua pertanyaan:
dan
Segala sesuatu yang melewati kueri kedua ditandai sebagai komentar :
--', 'Derper')
Dalam
'
nama siswa bukan komentar, itu pembatas string penutup . Karena nama siswa adalah string, maka diperlukan sintaksis untuk menyelesaikan kueri hipotetis. Serangan injeksi hanya berfungsi ketika kueri SQL yang mereka berikan menghasilkan SQL yang valid .Diedit lagi sesuai komentar cerdik dan04
sumber
INSERT
, maka tanda kurung akan lebih masuk akal. Ini juga akan menjelaskan mengapa koneksi database tidak dalam mode read-only.INSERT
. Berpikir mundur,SELECT
toh itu tidak akan berjalan karena Insert of the Little Bobby Tables di tabel sudah akan menjatuhkan meja.Students
mengharapkan lebih dari hanya satu kolom (pernyataan asli / benar menyediakan dua kolom). Yang mengatakan, kehadiran kolom kedua bermanfaat untuk menunjukkan mengapa komentar diperlukan; dan karena seseorang tidak dapat mengubah nama Bobby, mungkin lebih baik meninggalkan apa adanya dengan sedikit pengamatan daripada ini sebagai catatan kaki.Katakanlah nama itu digunakan dalam variabel,
$Name
,.Anda kemudian menjalankan kueri ini :
Kode keliru menempatkan apa pun yang diberikan pengguna sebagai variabel.
Anda ingin menjadi SQL :
Tetapi pengguna yang pintar dapat menyediakan apa pun yang mereka inginkan:
Yang Anda dapatkan adalah:
Satu-
--
satunya komentar sisa baris.sumber
Seperti orang lain sudah tunjukkan,
');
penutupan pernyataan asli dan kemudian pernyataan kedua mengikuti. Sebagian besar kerangka kerja, termasuk bahasa seperti PHP, sekarang memiliki pengaturan keamanan default yang tidak memungkinkan banyak pernyataan dalam satu string SQL. Dalam PHP, misalnya, Anda hanya dapat menjalankan beberapa pernyataan dalam satu string SQL dengan menggunakanmysqli_multi_query
fungsi.Anda dapat, bagaimanapun, memanipulasi pernyataan SQL yang ada melalui injeksi SQL tanpa harus menambahkan pernyataan kedua. Katakanlah Anda memiliki sistem masuk yang memeriksa nama pengguna dan kata sandi dengan pilihan sederhana ini:
Jika Anda memberikan
peter
sebagai nama pengguna dansecret
kata sandi, string SQL yang dihasilkan akan terlihat seperti ini:Semuanya baik. Sekarang bayangkan Anda memberikan string ini sebagai kata sandi:
Maka string SQL yang dihasilkan adalah:
Itu akan memungkinkan Anda untuk masuk ke akun apa pun tanpa mengetahui kata sandi. Jadi Anda tidak perlu dapat menggunakan dua pernyataan untuk menggunakan injeksi SQL, meskipun Anda dapat melakukan lebih banyak hal yang merusak jika Anda mampu menyediakan beberapa pernyataan.
sumber
Tidak,
'
bukan komentar di SQL, tetapi pembatas.Ibu seharusnya programmer database membuat permintaan yang tampak seperti:
(misalnya) untuk menambah siswa baru, di mana
$xxx
konten variabel diambil langsung dari formulir HTML, tanpa memeriksa format atau keluar dari karakter khusus.Jadi jika
$firstName
berisiRobert'); DROP TABLE students; --
program database akan mengeksekusi permintaan berikut secara langsung pada DB:yaitu. itu akan mengakhiri awal pernyataan penyisipan, mengeksekusi kode jahat apa pun yang diinginkan cracker, kemudian berkomentar apa pun sisa kode mungkin ada.
Mmm, saya terlalu lambat, saya sudah melihat 8 jawaban sebelum saya di band oranye ... :-) Topik yang populer, sepertinya.
sumber
TL; DR
Ini menjatuhkan (menghapus) tabel siswa.
( Semua contoh kode dalam jawaban ini dijalankan pada server database PostgreSQL 9.1.2. )
Untuk memperjelas apa yang terjadi, mari coba ini dengan tabel sederhana yang hanya berisi bidang nama dan tambahkan satu baris:
Mari kita asumsikan aplikasi menggunakan SQL berikut untuk memasukkan data ke dalam tabel:
Ganti
foobar
dengan nama siswa yang sebenarnya. Operasi memasukkan normal akan terlihat seperti ini:Saat kami menanyakan tabel, kami mendapatkan ini:
Apa yang terjadi ketika kita memasukkan nama Little Bobby Tables ke dalam tabel?
Injeksi SQL di sini adalah hasil dari nama siswa yang mengakhiri pernyataan dan termasuk
DROP TABLE
perintah terpisah ; dua tanda hubung pada akhir input dimaksudkan untuk mengomentari kode sisa yang jika tidak akan menyebabkan kesalahan. Baris terakhir dari output mengonfirmasi bahwa server database telah menjatuhkan tabel.Penting untuk diperhatikan bahwa selama
INSERT
operasi aplikasi tidak memeriksa input untuk setiap karakter khusus, dan oleh karena itu memungkinkan input sewenang-wenang untuk dimasukkan ke dalam perintah SQL. Ini berarti bahwa pengguna jahat dapat memasukkan, ke dalam bidang yang biasanya dimaksudkan untuk input pengguna, simbol-simbol khusus seperti tanda kutip bersama dengan kode SQL sewenang-wenang untuk menyebabkan sistem database untuk mengeksekusinya, maka dari itu injeksi SQL .Hasil?
Injeksi SQL adalah database yang setara dengan kerentanan eksekusi kode arbitrer jarak jauh dalam sistem operasi atau aplikasi. Dampak potensial dari serangan injeksi SQL yang sukses tidak dapat diremehkan - tergantung pada sistem database dan konfigurasi aplikasi, ini dapat digunakan oleh penyerang untuk menyebabkan kehilangan data (seperti dalam kasus ini), mendapatkan akses tidak sah ke data, atau bahkan mengeksekusi kode arbitrer pada mesin host itu sendiri.
Seperti dicatat oleh komik XKCD, salah satu cara untuk melindungi terhadap serangan injeksi SQL adalah membersihkan sanitas basis data, seperti dengan melarikan diri dari karakter khusus, sehingga mereka tidak dapat memodifikasi perintah SQL yang mendasarinya dan karena itu tidak dapat menyebabkan eksekusi kode SQL sewenang-wenang. Jika Anda menggunakan query parameter, seperti dengan menggunakan
SqlParameter
dalam ADO.NET, input akan, setidaknya, secara otomatis dibersihkan untuk menjaga terhadap injeksi SQL.Namun, membersihkan input pada level aplikasi mungkin tidak menghentikan teknik injeksi SQL yang lebih canggih. Misalnya, ada cara untuk menghindari
mysql_real_escape_string
fungsi PHP . Untuk perlindungan tambahan, banyak sistem database mendukung pernyataan yang disiapkan . Jika diimplementasikan dengan benar di backend, pernyataan yang disiapkan dapat membuat injeksi SQL tidak mungkin dengan memperlakukan input data secara semantik terpisah dari sisa perintah.sumber
Katakanlah Anda secara naif menulis metode pembuatan siswa seperti ini:
Dan seseorang memasukkan namanya
Robert'); DROP TABLE STUDENTS; --
Apa yang dijalankan pada database adalah permintaan ini:
Titik koma mengakhiri perintah sisipkan dan memulai yang lain; - komentar keluar dari sisa baris. Perintah DROP TABLE dieksekusi ...
Inilah sebabnya mengapa parameter bind adalah hal yang baik.
sumber
Kutipan tunggal adalah awal dan akhir dari sebuah string. Tanda titik koma adalah akhir dari sebuah pernyataan. Jadi jika mereka melakukan seleksi seperti ini:
SQL akan menjadi:
Pada beberapa sistem,
select
akan dijalankan pertama diikuti olehdrop
pernyataan! Pesannya adalah: DONT EMBED VALUES INTO YOUR SQL. Alih-alih menggunakan parameter!sumber
Yang
');
mengakhiri kueri, itu tidak memulai komentar. Kemudian ia menjatuhkan tabel siswa dan mengomentari sisa kueri yang seharusnya dieksekusi.sumber
Penulis database mungkin melakukan
Jika student_name adalah yang diberikan, itu melakukan seleksi dengan nama "Robert" dan kemudian menjatuhkan tabel. Bagian "-" mengubah sisa kueri yang diberikan menjadi komentar.
sumber
Dalam hal ini, 'bukan karakter komentar. Ini digunakan untuk membatasi literal string. Artis komik mengandalkan gagasan bahwa sekolah tersebut memiliki sql dinamis di suatu tempat yang terlihat seperti ini:
Jadi sekarang karakter 'mengakhiri string literal sebelum programmer mengharapkannya. Dikombinasikan dengan; karakter untuk mengakhiri pernyataan, penyerang sekarang dapat menambahkan sql apa pun yang mereka inginkan. The - komentar di akhir adalah untuk memastikan sql yang tersisa dalam pernyataan asli tidak mencegah permintaan dari kompilasi di server.
FWIW, saya juga berpikir komik tersebut memiliki rincian penting yang salah: jika Anda berpikir tentang membersihkan input basis data Anda, seperti yang disarankan komik, Anda masih melakukannya dengan salah. Sebagai gantinya, Anda harus berpikir dalam hal mengkarantina input basis data Anda, dan cara yang benar untuk melakukan ini adalah melalui permintaan parameter.
sumber
The
'
karakter dalam SQL digunakan untuk konstanta string. Dalam hal ini digunakan untuk mengakhiri string konstan dan bukan untuk komentar.sumber
Beginilah cara kerjanya: Mari kita anggap administrator sedang mencari catatan siswa
Karena akun admin memiliki hak tinggi menghapus tabel dari akun ini dimungkinkan.
Kode untuk mengambil nama pengguna dari permintaan adalah
Sekarang kueri akan menjadi seperti ini (untuk mencari tabel siswa)
Kueri yang dihasilkan menjadi
Karena input pengguna tidak disanitasi, kueri di atas telah dimanipulasi menjadi 2 bagian
Tanda hubung ganda (-) hanya akan mengomentari bagian yang tersisa dari permintaan.
Ini berbahaya karena dapat membatalkan otentikasi kata sandi, jika ada
Yang pertama akan melakukan pencarian normal.
Yang kedua akan menjatuhkan tabel siswa jika akun memiliki hak istimewa yang memadai (Umumnya admin sekolah akan menjalankan permintaan tersebut dan akan memiliki hak istimewa yang dibicarakan di atas).
sumber
SELECT* FROM sutdents ...
- Anda lupa "s". Inilah yang Anda jatuhkan.DROP TABLE STUDENTS;
Anda tidak perlu memasukkan data formulir untuk membuat injeksi SQL.
Tidak ada yang menunjukkan ini sebelumnya sehingga saya mungkin mengingatkan beberapa dari Anda.
Sebagian besar kami akan mencoba untuk menambal input formulir. Tapi ini bukan satu-satunya tempat di mana Anda bisa diserang dengan injeksi SQL. Anda dapat melakukan serangan sangat sederhana dengan URL yang mengirim data melalui permintaan GET; Pertimbangkan contoh penebangan:
URL Anda akan terlihat di http://yoursite.com/show?id=1
Sekarang seseorang dapat mencoba sesuatu seperti ini
Coba ganti table_name dengan nama tabel asli. Jika dia mendapatkan nama meja Anda dengan benar, mereka akan mengosongkan meja Anda! (Sangat mudah untuk memaksa paksa URL ini dengan skrip sederhana)
Kueri Anda akan terlihat seperti ini ...
Contoh kode rentan PHP menggunakan PDO:
Solusi - gunakan metode persiapan PDO () & bindParam ():
sumber