Contoh Dan Pencegahan SQL Injeksi Di Laravel
Sebagai developer yang membuat aplikasi, Anda memiliki kekuatan besar di ujung jari Anda. Namun, Anda juga memiliki tanggung jawab untuk menjaga keamanan data yang disimpan oleh aplikasi. Structured Query Language (SQL) adalah sistem manajemen basis data relasional untuk developer perangkat lunak. Injeksi SQL adalah masalah keamanan lama dan sangat umum di SQL.
Posting ini menjelaskan cara melakukan injeksi SQL di aplikasi Laravel Anda dan menyarankan beberapa tindakan pencegahan. Pertama, mari kita lihat apa itu injeksi SQL. Setelah itu, kita akan melihat beberapa contoh injeksi SQL di Laravel dan beberapa cara untuk mencegahnya.
Dengan asumsi bahwa pengelola alat mencakup semua yang terkait dengan keamanan dapat memberi Anda rasa aman yang salah saat menggunakan kerangka kerja atau alat. Laravel menyediakan banyak cara aman untuk bekerja dengan SQL. Namun, ada baiknya belajar tentang apa yang tidak tercakup. Lanjutkan membaca untuk mempelajari tentang beberapa kasus penggunaan dan fitur Laravel yang dapat mengekspos aplikasi Anda ke injeksi SQL.
Sebelum masuk ke contoh injeksi SQL Laravel, mari kita lihat apa itu injeksi SQL.Apa itu Injeksi SQL?
Peretas dapat menyuntikkan kode berbahaya dan melakukan operasi yang lebih serius pada basis data.
Pertama, mari kita bicara tentang injeksi SQL menggunakan contoh dunia nyata. Misalkan Anda memiliki aplikasi web yang menampilkan profil pengguna Anda melalui URL berikut:
https://example.com/profile.php/?user=john.doeUntuk mengambil data untuk john.doe pengguna saat ini, kueri berikut dijalankan:
SELECT * FROM users WHERE username = 'john.doe'
Saat mencoba melakukan injeksi SQL, seorang peretas dapat mengatur nilai parameter pengguna sebagai berikut:
https://example.com/profile.php/?user=john.doe’ OR 2=2;-- Kueri SQL berikut dijalankan untuk permintaan HTTP di atas.SELECT * FROM users WHERE username = 'john.doe' OR 2=2;--'
Kueri SQL di atas selalu mengembalikan true karena 2 = 2 selalu benar. Juga, jika Anda menggunakan kata kunci OR, seluruh ekspresi mengembalikan true jika salah satunya benar. Oleh karena itu, kueri di atas mengembalikan semua baris dalam tabel "pengguna". Ini adalah contoh klasik injeksi SQL.
Kerentanan ini dapat memungkinkan peretas untuk menyuntikkan kode berbahaya dan melakukan operasi yang lebih serius pada basis data. Dalam posting terperinci ini, Anda dapat mempelajari lebih lanjut tentang apa itu injeksi SQL, berbagai jenis injeksi SQL, dan praktik terbaik yang direkomendasikan.
Injeksi SQL Laravel
Laravel adalah kerangka kerja PHP open source gratis. Ini mengikuti pola desain MVC dan memiliki alat bawaan untuk melakukan tugas-tugas seperti otentikasi pengguna, perutean, dan operasi basis data.
Dengan Eloquent ORM, Anda dapat membuat aplikasi Laravel kecil yang membaca dan menulis data ke database SQL tanpa menulis kueri SQL mentah apa pun. Artinya, Anda tidak perlu menulis kueri seperti "SELECT * FROM table" untuk membaca data dari SQL. Namun, Laravel mendukung kueri SQL mentah. Ini karena tugas yang Anda perlukan mungkin memerlukan kueri mentah.
Sekarang mari kita lihat beberapa contoh injeksi Laravel SQL dan kemungkinan cara untuk mencegah serangan.Contoh 1: Menggunakan Metode Mentah
RawMethods adalah cara yang bagus untuk memungkinkan developer menggunakan kueri mentah hanya di bagian tertentu dari kueri basis data mereka. Contoh Metode Raw Laravel termasuk selectRaw, whereRaw, dan orderByRaw. Namun, RawMethods rentan terhadap injeksi SQL, dan dokumentasi resmi mengatakan: "Laravel tidak dapat menjamin bahwa kueri yang menggunakan ekspresi mentah akan dilindungi dari kerentanan injeksi SQL."
Mari kita lihat kode berikut untuk menunjukkan injeksi SQL di whereRaw RawMethod.DB::table('posts')
->select('postTitle', 'postBody')
->whereRaw('id =' . $id)->first();
Contoh kode di atas harus mengembalikan satu baris dari tabel posting. Atau, jika pos dengan ID yang ditentukan tidak ada, tidak ada apa-apa. Namun, kode ini memiliki perilaku yang tidak diinginkan ketiga. Nilai id ditentukan oleh input pengguna. Mari kita lihat apa yang terjadi ketika pengguna memasukkan nilai berikut:
https://example.com/post/11 AND 1=1 Permintaan HTTP di atas akan menjalankan kueri SQL berikut:SELECT postTitle, postBody FROM posts WHERE id = 11 AND 1=1
Aplikasi mengembalikan baris dengan ID 11 seperti yang diharapkan. Ini karena 1 = 1 selalu benar. Namun, misalkan seorang hacker selalu mengubah 1 = 1 menjadi sesuatu yang palsu. Berikut ini contohnya:
SELECT postTitle, postBody FROM posts WHERE id = 11 AND 1=2
Ini menyebabkan aplikasi mengembalikan nol baris atau macet. Perilaku ini menunjukkan bahwa ada kerentanan injeksi SQL di bagian whereRaw dari kueri pertama.
Pencegahan
Orang yang menggunakan Laravel disarankan untuk menghindari pertanyaan mentah sebanyak mungkin. Dengan melakukannya, Anda dapat menikmati beberapa fitur keamanan yang sudah ada di dalam kerangka kerja. Namun, jika Anda perlu menggunakan kueri mentah, Anda perlu memastikan bahwa Anda melakukan validasi sisi server dari input pengguna.
Salah satu cara untuk memperbaiki kerentanan dalam contoh ini adalah dengan memverifikasi bahwa nilai id adalah bilangan bulat. Anda dapat melakukannya dengan kode berikut:
$validator = Validator::make(['id' => $id], [
'id' => 'required|numeric'
]);
if ($validator->fails()) {
abort(404);
}else {
//Run query
}
Perbaikan lainnya adalah menulis ulang kueri pertama dengan kueri berparameter.
DB::table('posts')
->select('postTitle', 'postBody')
->whereRaw('id = ?', $id)->first();
Sebagai pengganti nilai id, kami menyediakan nilai id yang sebenarnya sebagai parameter kedua whereRaw.
Contoh 2: Menggunakan DB::statement
Jika Anda hanya ingin menjalankan kueri, Laravel memiliki metode pernyataan DB :: untuk itu. Ia menerima kueri SQL mentah sebagai parameter, tetapi tidak sepenuhnya tercakup oleh fitur keamanan bawaan Laravel. DB: Mari kita lihat kode berikut untuk menunjukkan cara kerja pernyataan.
DB::statement("UPDATE users SET password=".$newPassword. " WHERE username =" . $username);
Kode di atas perlu mengubah kata sandi untuk pengguna tertentu dengan memperbarui baris yang benar di tabel pengguna. Namun, jika pengguna memasukkan "Siapa saja ATAU 1 = 1" sebagai nama pengguna dan "123456" sebagai kata sandi, hasil yang berbeda akan terjadi.
Kueri berikut dijalankanUPDATE users SET password="123456 " WHERE username ="Anyone" OR 1=1
Kueri di atas menetapkan kata sandi untuk semua pengguna ke "123456". Jenis eksploitasi ini memungkinkan peretas mengakses beberapa akun pengguna di situs web.
Pencegahan
Sekali lagi, memvalidasi input pengguna berguna. Juga,? Anda dapat menggunakan sebagai placeholder input pengguna, menentukan nilai aktual sebagai parameter kedua dari metode pernyataan DB :: yang diterapkan selanjutnya.DB::statement("UPDATE users SET password=? WHERE username =?", [$password, $username]);
Contoh 3: Pesan kesalahan
Aplikasi yang dibangun dengan Laravel dapat menampilkan informasi sensitif seperti kueri basis data selama pengecualian yang luar biasa.DB::statement("SELECT * FROM users WHERE id=".$Id);
Kode di atas akan menampilkan pesan kesalahan berikut di browser pengguna jika ID yang dimasukkan tidak valid (nilai non-integer). Seperti yang Anda lihat di tangkapan layar ini, halaman kesalahan menampilkan informasi sensitif tentang kueri SQL yang relevan. Jenis informasi ini membantu peretas memahami logika di bawah aplikasi dan memaparkannya pada potensi serangan:
Pencegahan
Uji aplikasi Anda untuk jenis pengecualian yang tidak tertangani ini sebelum mendorongnya ke produksi. Ada juga cara untuk mematikan jenis pelaporan kesalahan ini sama sekali di Laravel. Kami menyarankan Anda menonaktifkan pelaporan kesalahan di lingkungan produksi. Anda dapat terus menemukan detail berguna tentang kerusakan dan kesalahan aplikasi di file log Laravel.
Untuk menonaktifkan kesalahan penyesuaian halaman pelaporan, buka file .env dan ubah nilai APP_DEBUG dari true menjadi false. Kode terakhir terlihat seperti ini:
APP_DEBUG = false
Untuk menutup
Singkatnya, injeksi SQL sayangnya milik Laravel. Namun, input pengguna dan validasi kueri berparameter dapat membantu mengurangi risiko injeksi SQL.
Keamanan untuk aplikasi Laravel adalah proses yang berkelanjutan. Selain itu, tidak semua kemungkinan kerentanan dan solusi dapat tercakup dalam satu pos. Oleh karena itu, selalu ikuti praktik terbaik dan perbarui kode serta alat Anda.
Postingan ini ditulis oleh Pius Aboyi. Pius adalah developer seluler dan web dengan pengalaman lebih dari 4 tahun membangun untuk platform Android. Dia menulis kode dalam Java, Kotlin, dan PHP. Dia suka menulis tentang teknologi dan membuat tutorial cara untuk developer.