Praktik: Mengamankan formulir login dari serangan dasar
Formulir login merupakan salah satu komponen penting dalam aplikasi web yang sering menjadi target serangan seperti SQL Injection dan Cross-Site Scripting (XSS). Memahami dan menerapkan teknik pengamanan yang tepat pada formulir login akan membantu mencegah akses tidak sah dan melindungi data pengguna.
1. Persiapan Lingkungan
1.1. Instalasi LAMP Stack
Pastikan server Ubuntu 24.04 Anda telah terinstal Apache, MySQL, dan PHP (LAMP Stack). Jika belum, ikuti langkah-langkah berikut:
1. Perbarui daftar paket:
sudo apt update
2. Instal Apache:
sudo apt install apache2 -y
3. Instal MySQL:
sudo apt install mysql-server -y
Setelah instalasi, amankan MySQL dengan menjalankan:
sudo mysql_secure_installation
4. Instal PHP:
sudo apt install php libapache2-mod-php php-mysql -y
1.2. Konfigurasi Direktori Proyek
Buat direktori untuk proyek Anda dan atur izin yang sesuai:
sudo mkdir /var/www/html/secure-login sudo chown -R $USER:$USER /var/www/html/secure-login
2. Membuat Formulir Login yang Aman
2.1. Struktur Dasar Formulir Login
Buat file `index.php` di direktori proyek dengan konten berikut:
<?php session_start(); ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <title>Formulir Login Aman</title> </head> <body> <h2>Login</h2> <?php if (isset($_SESSION['error'])) { echo '<p style="color:red;">' . htmlspecialchars($_SESSION['error']) . '</p>'; unset($_SESSION['error']); } ?> <form action="authenticate.php" method="post"> <label for="username">Nama Pengguna:</label> <input type="text" id="username" name="username" required> <br> <label for="password">Kata Sandi:</label> <input type="password" id="password" name="password" required> <br> <input type="submit" value="Masuk"> </form> </body> </html>
2.2. Proses Autentikasi dengan Prepared Statements
Buat file `authenticate.php` dengan konten berikut untuk memproses input pengguna dan mencegah SQL Injection:
<?php session_start(); $host = 'localhost'; $dbname = 'nama_database'; $username = 'nama_pengguna'; $password = 'kata_sandi'; try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { die("Koneksi gagal: " . htmlspecialchars($e->getMessage())); } if ($_SERVER["REQUEST_METHOD"] == "POST") { $user = trim($_POST['username']); $pass = trim($_POST['password']); if (empty($user) || empty($pass)) { $_SESSION['error'] = 'Nama pengguna dan kata sandi harus diisi.'; header('Location: index.php'); exit(); } $stmt = $pdo->prepare("SELECT password FROM users WHERE username = :username"); $stmt->bindParam(':username', $user, PDO::PARAM_STR); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row && password_verify($pass, $row['password'])) { $_SESSION['user'] = $user; header('Location: dashboard.php'); exit(); } else { $_SESSION['error'] = 'Nama pengguna atau kata sandi salah.'; header('Location: index.php'); exit(); } } ?>
Penjelasan:
- Koneksi Database: Menggunakan PDO untuk koneksi yang aman ke database.
- Prepared Statements: Mencegah SQL Injection dengan memisahkan data dari perintah SQL.
- Validasi Input: Memastikan bahwa input tidak kosong sebelum diproses.
- Password Hashing: Menggunakan `password_verify()` untuk memverifikasi kata sandi yang telah di-hash.
3. Mencegah Cross-Site Scripting (XSS)
Untuk mencegah XSS, pastikan semua output yang ditampilkan ke pengguna telah di-escape dengan `htmlspecialchars()`. Contoh implementasi telah ditunjukkan pada bagian sebelumnya di mana pesan kesalahan ditampilkan.
Selain itu, Anda dapat mengatur Content Security Policy (CSP) untuk membatasi sumber daya yang dapat dimuat oleh browser, sehingga mencegah eksekusi skrip berbahaya. Tambahkan header berikut pada konfigurasi Apache:
<IfModule mod_headers.c> Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self';" </IfModule>
4. Penggunaan HTTPS
Pastikan komunikasi antara klien dan server dienkripsi dengan HTTPS. Anda dapat menggunakan Let's Encrypt untuk mendapatkan sertifikat SSL.