PHP adalah bahasa pemrograman web sisi server paling populer di dunia. Menurut data W3Techs dari April 2019, 79% situs web didukung oleh PHP. Di antara situs web tersebut adalah Facebook, Yahoo, dan Wikipedia
Karena PHP sangat populer, keamanan PHP sangat penting dan jumlah aplikasi PHP yang rentan sangat banyak. Sebagian besar aplikasi web PHP berbagi bagian kode atau skrip dengan aplikasi web lainnya. Jika potongan kode yang dibagikan ditemukan rentan, semua aplikasi yang menggunakannya juga rentan
Penyebab Kerentanan
Sebagian besar kerentanan adalah hasil dari kebiasaan pengkodean yang buruk atau kurangnya kesadaran keamanan aplikasi PHP di kalangan pengembang. Penyebab utamanya adalah fakta bahwa input pengguna diperlakukan sebagai tepercaya
Saat Anda menulis kode, Anda harus menerapkan dua prosedur utama. validasi dan sanitasi. Jika Anda menerapkan kedua prosedur ini untuk data pengguna, Anda memastikan bahwa apa yang diproses dan dijalankan valid dan memenuhi kriteria yang ditentukan. Anda juga harus memastikan bahwa data keluaran HTML diloloskan sehingga tidak ada kode berbahaya yang dijalankan jika penyerang memasukkannya ke dalam konten. Jika Anda mengikuti prosedur sederhana dan dasar tertentu untuk setiap halaman web, Anda secara signifikan meminimalkan kemungkinan terkena masalah keamanan kritis
Pemrograman Berorientasi Objek (OOP) memainkan peran besar dalam menerapkan prosedur keamanan PHP. Kode yang dapat digunakan kembali yang ditulis dengan baik dapat sangat meningkatkan keamanan sistem secara keseluruhan. Ini memastikan bahwa prosedur pemrosesan data yang sama selalu diikuti
Injeksi SQL di PHP
SQL Injection adalah salah satu kerentanan aplikasi web yang paling berbahaya. Itu secara konsisten diberi peringkat nomor satu oleh OWASP dan membayangi kerentanan lain seperti Cross-site Scripting (XSS) atau Cross-site Request Forgery (CSRF). Jika Anda memasukkan input pengguna langsung ke kueri SQL (tidak divalidasi/tidak bersih), penyerang dapat memanipulasi kueri itu sendiri. Mereka dapat memaksanya untuk mengembalikan hasil yang berbeda dari yang diharapkan
Serangan SQL Injection yang berhasil dapat mengakibatkan pelanggaran data, yang dapat mengekspos nama pengguna, kata sandi, alamat email, informasi kartu kredit, dan data sensitif lainnya. Dalam beberapa kasus, bahkan serangan umum dapat mengakibatkan kompromi seluruh server web
Contoh Kode Tidak Aman
Dalam contoh kode sumber berikut, parameter article diteruskan ke kueri dengan cara yang tidak aman
Pengguna jahat dapat mengirimkan nilai yang dibuat khusus yang akan disertakan dalam kueri SQL sebelum kueri dijalankan. Sebagai contoh
1'+union+select+1,version(),3'_Kueri menjadi
$query = "SELECT * FROM articles WHERE articleid = '1'+union+select+1,version(),3''";Penyerang dapat menggunakan permintaan yang mirip dengan kode di atas untuk menghitung semua tabel/kolom database dan mendapatkan akses ke informasi sensitif
Solusi untuk masalah ini adalah dengan menggunakan kueri SQL berparameter (pernyataan yang disiapkan). Jika Anda menggunakan kueri berparameter, Anda memberi tahu database, bagian mana yang merupakan kueri dan mana data (input pengguna) karena Anda mengirimkannya dalam dua permintaan terpisah. Ini menghilangkan kemungkinan mencampur input pengguna dan kueri SQL
Direkomendasikan agar Anda menggunakan PHP Data Objects (PDO) untuk mengeksekusi pernyataan yang telah disiapkan dalam skrip PHP Anda. PDO termasuk dalam versi terbaru PHP. Itu diperkenalkan di PHP 5. 1 dan tersedia sebagai ekstensi PECL di PHP 5. 0. Itu tidak dapat diakses untuk versi PHP sebelumnya
Hindari menggunakan ekstensi mysql dan mysqli dalam kode PHP Anda. Mereka sudah usang/usang tetapi masih sering digunakan dan Anda dapat menulis ulang kode untuk menggunakan PDO
Contoh Kode Aman
Dalam contoh file PHP ini, Anda tidak meneruskan user_id ke kueri secara langsung. Sebagai gantinya, Anda menggantinya dengan placeholder. Basis data backend akan mengetahui apa yang harus diganti dengan placeholder saat Anda menjalankan fungsi execute()
// User ID must not be empty, must be numeric and must be less than 5 characters long if((!empty($_GET['user_id'])) && (is_numeric($_GET['user_id'])) && (mb_strlen($_GET['user_id'])<5)) { $servername = "localhost"; $username = "username"; $password = "password"; $database = "dbname"; // Establish a new connection to the SQL server using PDO try { $conn = new PDO("mysql:host=$servername;dbname=$database", $username, $password); // Assign user input to the $user_id variable $user_id = $_GET['user_id']; // Prepare the query and set a placeholder for user_id $sth = $conn->prepare('SELECT user_name, user_surname FROM users WHERE user_id=?'); // Execute the query by providing the user_id parameter in an array $sth->execute(array($user_id)); // Fetch all matching rows $user = $sth->fetch(); // If there is a matching user, display their info if(!empty($user)) { echo "Welcome ".$user['user_name']." ".$user['user_surname']; } else { echo "No user found"; } // Close the connection $dbh = null; } catch(PDOException $e) { echo "Connection failed."; } } else { echo "User ID not specified or invalid."; }Untuk detail lebih lanjut tentang mencegah Injeksi SQL di PHP, lihat artikel berikut. Mencegah Injeksi SQL