Anda di halaman 1dari 5

Banyak pengembang web tidak menyadari tentang bagaimana query SQL dapat dirusak, dan menganggap bahwa sebuah

query SQL adalah perintah terpercaya. Ini berarti bahwa query SQL dapat menghindari kontrol akses, sehingga melewati otentikasi standar dan pemeriksaan otorisasi, dan kadang-kadang bahkan mungkin query SQL memungkinkan akses ke host perintah sistem operasi tingkat. Langsung Injeksi SQL Command adalah teknik di mana seorang penyerang menciptakan atau mengubah yang sudah ada perintah SQL untuk mengekspos data yang disembunyikan, atau untuk menimpa yang berharga, atau bahkan untuk menjalankan perintah sistem tingkat yang berbahaya pada host database. Hal ini dilakukan dengan aplikasi mengambil input user dan mengombinasikan dengan parameter statis untuk membangun sebuah query SQL. Contoh berikut didasarkan pada kisah nyata, sayangnya. Karena kurangnya validasi input dan menghubungkan ke database atas nama superuser atau orang yang dapat membuat pengguna, penyerang dapat membuat superuser dalam database Anda. Contoh # 1 Memisahkan hasil set ke dalam halaman ... dan membuat superuser (PostgreSQL)
<?php $ Offset = $ argv [0]; / / waspada, tidak ada validasi input! $ Query = "SELECT id, nama FROM ORDER BY LIMIT nama produk 20 OFFSET $ offset;"; $ Hasil = pg_query ($ conn, $ query); ?>

Pengguna biasa klik pada 'selanjutnya', link 'prev' dimana $ offset dikodekan ke dalam URL. Script mengharapkan bahwa $ masuk offset adalah angka desimal.Namun, bagaimana jika seseorang mencoba untuk istirahat di dengan menambahkan urlencode () 'd bentuk berikut untuk URL
0; masukkan ke pg_shadow (usename, usesysid, usesuper, usecatupd, passwd) pilih 'retak', usesysid, 't', 't', 'retak' dari pg_shadow mana usename = 'postgres'; -

Jika itu terjadi, maka script akan menyajikan akses superuser kepadanya. Perhatikan bahwa 0; adalah menyediakan yang valid offset untuk query asli dan untuk mengakhiri itu. Note : Ini adalah teknik umum untuk memaksa parser SQL untuk mengabaikan sisanya dari permintaan yang ditulis oleh pengembang dengan - yang merupakan tanda komentar di SQL. Sebuah cara yang layak untuk mendapatkan password adalah untuk menghindari pencarian halaman hasil. Satu-satunya penyerang perlu lakukan adalah untuk melihat apakah ada variabel disampaikan digunakan dalam pernyataan SQL yang tidak ditangani dengan benar. Filter ini dapat diatur umumnya dalam bentuk sebelumnya untuk menyesuaikan WHERE, ORDER BY, LIMIT dan OFFSET klausa dalam pernyataan SELECT.Jika database Anda mendukung membangun UNION, penyerang dapat mencoba untuk menambahkan query seluruh dengan yang asli ke daftar password dari tabel sewenang-wenang.Menggunakan bidang password terenkripsi sangat didorong.

Contoh # 2 Daftar out artikel ... dan beberapa password (server database)
<?php $ Query = "SELECT id, nama, dimasukkan, ukuran FROM produk MANA size = '$ size' ORDER BY LIMIT batas $ order $, $ offset; "; $ Hasil = odbc_exec ($ conn, $ query); ?>

Bagian statis dari query dapat dikombinasikan dengan pernyataan SELECT lain yang mengungkapkan semua password:
' serikat pilih '1 ', concat (uname ||'-'|| passwd) sebagai nama, '1971-0101', '0 'dari usertable; -

Jika permintaan ini (bermain dengan 'dan -) ditugaskan ke salah satu variabel yang digunakan dalam $ query, permintaan binatang terbangun. SQL UPDATE adalah juga rentan terhadap serangan. Pertanyaan ini juga terancam dengan memotong dan menambahkan sebuah query yang sama sekali baru untuk itu. Tapi penyerang mungkin biola dengan klausa SET.Dalam kasus ini beberapa informasi skema harus dimiliki untuk memanipulasi query berhasil. Hal ini dapat diperoleh dengan memeriksa nama-nama variabel bentuk, atau hanya cukup kasar memaksa. Tidak begitu banyak konvensi penamaan untuk bidang menyimpan password atau username. Contoh # 3 Dari reset password ... untuk mendapatkan hak lebih (server database)
<?php $ Query = "UPDATE SET usertable pwd = '$ pwd' WHERE uid = '$ uid';"; ?>

Tapi pengguna berbahaya sumbits nilai 'atau uid seperti'%% admin '; - untuk $ uid untuk mengubah password admin, atau hanya menetapkan $ pwd untuk "hehehe', admin = 'ya', terpercaya = 100" (dengan ruang trailing) untuk mendapatkan hak lebih.Kemudian, permintaan akan diputar:
<?php / / $ Uid%% == admin 'atau uid seperti' '; $ Query = "UPDATE SET usertable pwd ='...'Uid =''MANA atau uid seperti '% admin%'; - "; / / $ Pwd == "hehehe ', admin =' ya ', terpercaya = 100" $ Query = "UPDATE SET usertable pwd = 'hehehe', admin = 'ya', terpercaya = 100 MANA ...; "; ?>

Sebuah contoh yang menakutkan bagaimana perintah sistem operasi tingkat dapat diakses di beberapa host database.

Contoh # 4 Menyerang sistem operasi host database yang (MSSQL Server)


<?php $ Query = "SELECT * FROM produk WHERE id LIKE '% $ prod%'"; $ Hasil = mssql_query ($ query); ?>

Jika penyerang menyampaikan suatu nilai% 'master exec .. xp_cmdshell' bersih pengguna testpass tes / ADD '- untuk $ prod, maka permintaan $ akan menjadi:
<?php $ Query = "SELECT * FROM produk WHERE id LIKE '% a%' exec master .. xp_cmdshell pengguna bersih 'tes ADD' testpass / - "; $ Hasil = mssql_query ($ query); ?>

MSSQL Server mengeksekusi pernyataan SQL dalam batch termasuk perintah untuk menambahkan user baru ke database account lokal. Jika aplikasi ini berjalan sebagai sa dan layanan MSSQLSERVER berjalan dengan hak akses yang memadai, penyerang sekarang akan memiliki account yang dapat digunakan untuk mengakses mesin ini. Note : Beberapa contoh di atas adalah terikat ke server database tertentu. Ini tidak berarti bahwa serangan serupa tidak mungkin terhadap produk lainnya. Server database Anda mungkin juga rentan dengan cara lain.

Gambar milik xkcd

Penghindaran Teknik
Sementara itu tetap jelas bahwa penyerang harus memiliki setidaknya beberapa pengetahuan tentang arsitektur database dalam rangka untuk melakukan sebuah serangan yang berhasil, memperoleh informasi ini sering sangat sederhana. Sebagai contoh, jika database adalah bagian dari open source atau publik yang tersedia paket perangkat lunak dengan instalasi default, informasi ini benar-benar terbuka dan tersedia. Informasi ini dapat juga diungkapkan oleh sumber tertutup kode - bahkan jika itu disandikan, dikaburkan, atau dikompilasi - dan bahkan dengan kode Anda sendiri melalui tampilan pesan kesalahan. Metode lain termasuk pengguna meja umum dan nama kolom. Sebagai contoh, form login yang menggunakan tabel 'user' dengan 'id' kolom nama, 'username', dan 'password'. Serangan ini terutama didasarkan pada pemanfaatan kode tidak ditulis dengan keamanan dalam pikiran. Jangan pernah percaya apapun jenis masukan, terutama yang berasal dari sisi klien, meskipun itu berasal dari kotak pilih, field input tersembunyi atau cookie. Contoh pertama menunjukkan bahwa seperti permintaan bersalah dapat menyebabkan bencana.

Jangan menghubungkan ke database sebagai superuser atau sebagai pemilik database.Gunakan selalu disesuaikan dengan hak akses pengguna yang sangat terbatas.
y

Periksa apakah input yang diberikan memiliki jenis data yang diharapkan.PHP memiliki berbagai fungsi input validasi, dari yang paling sederhana yang ditemukan dalam Fungsi Variabel dan Tipe Karakter Fungsi (misalnya is_numeric () , ctype_digit () masing-masing) dan seterusnya ke Expressions Perl Regular kompatibel dukungan.
y

Jika aplikasi menunggu input numerik, pertimbangkan verifikasi data dengan is_numeric () , atau diam-diam mengubah jenis dengan menggunakan settype () , atau menggunakan representasi numerik oleh sprintf () .
<?php settype ($ offset, 'bulat'); $ Query = "SELECT id, nama FROM ORDER BY LIMIT nama produk 20 OFFSET $ offset;"; / / Harap d perhatikan% dalam format string, menggunakan% s akan menjadi tidak berarti $ Query = sprintf ("SELECT id, nama FROM ORDER BY LIMIT nama produk 20% d offset;", Diimbangi $); ?>

Contoh # 5 Suatu cara yang lebih aman untuk menyusun query untuk paging

Quote setiap nilai numerik pengguna non disediakan yang dilewatkan ke database dengan database-spesifik fungsi melarikan diri string (misalnya mysql_real_escape_string () , sqlite_escape_string () , dll).Jika database-spesifik mekanisme melarikan diri string yang tidak tersedia, addslashes () dan str_replace () fungsi dapat berguna (tergantung pada jenis database).Lihat contoh pertama .Sebagai contoh menunjukkan, menambahkan tanda kutip untuk bagian statis dari query tidak cukup, membuat query ini dengan mudah crackable. Jangan mencetak informasi database tertentu, terutama tentang skema, dengan cara yang adil atau busuk.Lihat juga Pelaporan Kesalahan dan Kesalahan Penanganan dan Logging Fungsi .
y

Anda dapat menggunakan prosedur yang tersimpan dan kursor didefinisikan sebelumnya untuk mengakses data abstrak sehingga pengguna tidak langsung mengakses tabel atau pandangan, tetapi solusi ini memiliki dampak lain.

Selain itu, Anda mendapatkan keuntungan dari penebangan permintaan baik di dalam script Anda atau oleh database itu sendiri, jika mendukung penebangan. Jelas, penebangan tidak dapat mencegah setiap upaya berbahaya, tetapi dapat membantu untuk melacak kembali yang aplikasi telah dielakkan. Log tidak berguna dengan sendirinya, tetapi melalui informasi yang dikandungnya. Lebih rinci umumnya lebih baik daripada kurang.

Cara yang baik untuk melawan injeksi SQL untuk query tipe SELECT adalah menggunakan fungsi hash pada data dengan PHP dan database server. Sebagai contoh, adalah mungkin untuk menggunakan fungsi MySQL MD5 () untuk menghasilkan hash data-sisi server, dan fungsi setara di php web sisi server.

<?php $ Login = mysql_query ("pilih f_uname, f_passwd dari t_user mana MD5 (f_uname) = '". Md5 ($ uname) ".' Dan MD5 (f_passwd )='". md5 ($ )."'") passwd; ?> Dengan demikian, permintaan disuntikkan akan hancur dan akan menjadi jauh lebih sulit untuk memperoleh data dalam database. Gunakan kedua sisi hasil hash dalam perbandingan hash, eksekusi bukan query yang disuntikkan. Sayangnya, mungkin tidak bekerja dengan jenis lain dari query. saya hanya bermain-main dengan fungsi array_walk. Tiba-tiba saya bahwa hampir semua GLOBALS super array. Jadi apa yang saya temukan adalah bahwa saya dapat menerapkan fungsi array_walk ke GLOBALS super. Melakukan sehingga Anda secara otomatis menjalankan fungsi panggilan melalui GLOBALS Super Dengan potongan kode ini saya menulis Anda harus dapat mengamankan sebagian besar dari Anda input data. <?php class secure { function secureSuperGlobalGET(&$value, $key) { $_GET[$key] = htmlspecialchars(stripslashes($_GET[$key])); $_GET[$key] = str_ireplace("script", "blocked", $_GET[$key]); $_GET[$key] = mysql_escape_string($_GET[$key]); return $_GET[$key]; } function secureSuperGlobalPOST(&$value, $key) { $_POST[$key] = htmlspecialchars(stripslashes($_POST[$key])); $_POST[$key] = str_ireplace("script", "blocked", $_POST[$key]); $_POST[$key] = mysql_escape_string($_POST[$key]); return $_POST[$key]; } function secureGlobals() { array_walk($_GET, array($this, 'secureSuperGlobalGET')); array_walk($_POST, array($this, 'secureSuperGlobalPOST')); } } ?> Perhatikan bahwa Anda dapat mengubah ini dengan cara apapun sesuai dengan kebutuhan anda. Script ini telah diuji.