Keamanan Lanjutan PHP: CSRF, Session Hijacking, dan Password Hashing

By | 14 October 2025

Ketika aplikasi PHP kamu mulai memiliki pengguna aktif, transaksi, dan login sistem, ancaman keamanan menjadi semakin serius. Banyak serangan web tidak hanya datang dari “luar” tapi bisa muncul dari input pengguna yang tidak aman, sesi yang dicuri, atau form tanpa proteksi. Setelah memahami validasi form dan pencegahan SQL Injection & XSS, kini saatnya kita membahas tiga pilar keamanan lanjutan PHP:

  • CSRF Protection (Cross-Site Request Forgery)

  • Session Hijacking Protection

  • Password Hashing & Verification

1. CSRF (Cross-Site Request Forgery)

Apa itu CSRF?

CSRF adalah serangan di mana penyerang memaksa pengguna yang sedang login untuk melakukan tindakan tanpa disadari, seperti:

  • Menghapus data

  • Mengganti email

  • Mengirim transaksi

Contohnya, jika aplikasi tidak memiliki proteksi CSRF, penyerang bisa membuat halaman tersembunyi seperti:

<img src="https://example.com/delete.php?id=1">

Jika korban sedang login di example.com, maka data bisa terhapus otomatis tanpa konfirmasi.

Solusi: Gunakan CSRF Token

CSRF Token adalah string acak unik yang disertakan pada setiap form dan diverifikasi di server.

Contoh Implementasi:

Buat token saat sesi dimulai:

<?php
session_start();
if (empty($_SESSION['token'])) {
    $_SESSION['token'] = bin2hex(random_bytes(32));
}
?>

Tambahkan token ke form:

<form method="post" action="proses.php">
  <input type="hidden" name="token" value="<?= $_SESSION['token']; ?>">
  <button type="submit">Hapus Data</button>
</form>

Validasi token di proses.php:

<?php
session_start();
if (!isset($_POST['token']) || $_POST['token'] !== $_SESSION['token']) {
    die("Permintaan tidak valid!");
}
?>

Keuntungan:

  • Tiap form punya identitas unik.

  • Serangan otomatis dari luar domain tidak akan berhasil.

2. Session Hijacking (Pencurian Sesi)

Apa itu Session Hijacking?

Session hijacking terjadi ketika penyerang mencuri session ID pengguna agar bisa login sebagai orang lain tanpa password.

Biasanya dilakukan lewat:

  • Cookie yang tidak aman

  • URL yang mengandung ?sessionid=...

  • Serangan XSS yang mencuri cookie

Solusi 1: Gunakan session_regenerate_id()

Setiap kali pengguna login, ubah session ID lama menjadi baru untuk mencegah reuse.

<?php
session_start();
session_regenerate_id(true); // hapus ID lama
$_SESSION['user'] = $username;
?>

Solusi 2: Batasi Sesi Berdasarkan IP dan User Agent

Tambahkan pemeriksaan di setiap halaman yang butuh login.

<?php
session_start();
if (!isset($_SESSION['user'])) {
    header("Location: login.php");
    exit;
}

// Validasi tambahan
if ($_SESSION['ip'] !== $_SERVER['REMOTE_ADDR'] || 
    $_SESSION['ua'] !== $_SERVER['HTTP_USER_AGENT']) {
    session_destroy();
    die("Sesi tidak valid!");
}
?>

Saat login pertama kali:

<?php
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['ua'] = $_SERVER['HTTP_USER_AGENT'];
?>

Solusi 3: Gunakan Cookie Aman

Gunakan pengaturan berikut sebelum session_start():

<?php
ini_set('session.cookie_httponly', 1); // Tidak bisa diakses JS
ini_set('session.cookie_secure', 1);   // Hanya dikirim lewat HTTPS
ini_set('session.use_strict_mode', 1); // Tidak terima session ID palsu
session_start();
?>

3. Password Hashing & Verification

Kesalahan Umum Developer Pemula

Banyak aplikasi lama masih menyimpan password dalam bentuk plaintext (teks asli). Itu sama saja seperti menulis password di papan pengumuman.

Solusi Modern: Gunakan password_hash() dan password_verify()

Contoh Saat Registrasi

<?php
$password = $_POST['password'];
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

$stmt = $conn->prepare("INSERT INTO users (username, password) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $hashedPassword);
$stmt->execute();
?>

Contoh Saat Login

<?php
$stmt = $conn->prepare("SELECT password FROM users WHERE username=?");
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->bind_result($hashedPassword);
$stmt->fetch();

if (password_verify($_POST['password'], $hashedPassword)) {
    echo "Login sukses!";
} else {
    echo "Password salah!";
}
?>

Kelebihan:

  • password_hash() otomatis menambahkan salt (acak).

  • password_verify() mencocokkan secara aman tanpa tahu algoritma.

  • Bisa diupgrade algoritmanya tanpa ubah data lama.

Bonus: Batasi Upaya Login Gagal

Untuk mencegah brute force attack, simpan jumlah percobaan login di database atau session.

<?php
if (!isset($_SESSION['login_attempt'])) {
    $_SESSION['login_attempt'] = 0;
}

if ($_SESSION['login_attempt'] >= 3) {
    die("Terlalu banyak percobaan. Coba lagi nanti.");
}

// Setelah login gagal
$_SESSION['login_attempt']++;
?>

Kesimpulan

Fitur Keamanan Tujuan Solusi
CSRF Mencegah permintaan palsu dari luar domain Token unik per form
Session Hijacking Mencegah pencurian sesi login session_regenerate_id(), validasi IP & User-Agent
Password Hashing Melindungi password pengguna password_hash() & password_verify()

Dengan menggabungkan tiga teknik di atas, aplikasi PHP kamu akan jauh lebih aman, stabil, dan siap online secara profesional.

Category: PHP