Praktik: Mengamankan formulir login dari serangan dasar

From OnnoWiki
Jump to navigation Jump to search

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.


Pranala Menarik