PHP Security: Cara Mencegah SQL Injection & XSS Secara Benar dan Berkelanjutan

PHP Security: Cara Mencegah SQL Injection & XSS Secara Benar dan Berkelanjutan

Keamanan aplikasi web bukan lagi opsional, terutama untuk website bisnis. Dua jenis serangan yang paling sering menyebabkan kebocoran data dan kerugian finansial adalah:

  • SQL Injection
  • Cross-Site Scripting (XSS)

Ironisnya, kedua serangan ini sudah dikenal lebih dari 20 tahun, tetapi masih menjadi penyebab utama insiden keamanan hingga hari ini — termasuk di aplikasi PHP modern.

Masalahnya bukan karena PHP tidak aman, melainkan karena:

  • Implementasi yang salah
  • Kurangnya pemahaman konteks input & output
  • Developer terlalu percaya data dari user

Artikel ini membahas cara mencegah SQL Injection dan XSS di PHP secara menyeluruh, dari level kode hingga praktik production.


1. Memahami Ancaman: SQL Injection & XSS

1.1 Apa Itu SQL Injection?

SQL Injection terjadi ketika input user:

  • Langsung dimasukkan ke query SQL
  • Tanpa validasi & parameter binding

Dampak:

  • Bypass login
  • Dump database
  • Hapus data
  • Ambil data sensitif

1.2 Apa Itu XSS (Cross-Site Scripting)?

XSS terjadi ketika:

  • Data user ditampilkan kembali ke browser
  • Tanpa escaping yang benar

Dampak:

  • Session hijacking
  • Deface website
  • Pencurian data user
  • Malware injection

2. SQL Injection di PHP: Contoh Nyata & Cara Mencegahnya

2.1 Contoh Kode Rentan SQL Injection (SALAH)

$username = $_POST['username'];
$password = $_POST['password'];

$query = "SELECT * FROM users 
          WHERE username = '$username' 
          AND password = '$password'";

$result = mysqli_query($conn, $query);

Jika user input:

' OR 1=1 --

👉 Login langsung tembus.


3. Solusi Utama: Prepared Statement (WAJIB)

3.1 Contoh Aman dengan PDO

$stmt = $pdo->prepare(
  "SELECT * FROM users 
   WHERE username = :username 
   AND password = :password"
);

$stmt->execute([
  ':username' => $username,
  ':password' => $password
]);

📌 Prepared statement memisahkan data dari query, sehingga input tidak pernah dieksekusi sebagai SQL.


3.2 Prepared Statement dengan MySQLi

$stmt = $conn->prepare(
  "SELECT * FROM users WHERE username = ?"
);
$stmt->bind_param("s", $username);
$stmt->execute();

4. Kesalahan Fatal Terkait SQL Injection

❌ Escape manual (addslashes)
❌ Filter input tapi tetap concat string
❌ Mengandalkan frontend validation
❌ Percaya data dari internal API

📌 Satu-satunya solusi benar adalah parameter binding.


5. Validasi & Sanitasi Input (Lapisan Tambahan)

Prepared statement melindungi query, tapi validasi tetap penting.

Contoh Validasi

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
  throw new Exception("Email tidak valid");
}

📌 Validasi ≠ keamanan SQL
📌 Validasi = kualitas data


6. XSS di PHP: Contoh Nyata & Dampaknya

6.1 Contoh Kode Rentan XSS

echo $_GET['name'];

Jika user akses:

<script>alert('Hacked')</script>

👉 Script dieksekusi di browser.


7. Solusi Utama XSS: Output Escaping

7.1 Escape HTML dengan Benar

echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8');

📌 Escape saat OUTPUT, bukan saat input.


7.2 Contoh di Template (Blade / PHP Native)

<?= htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8') ?>

Laravel:

{{ $userInput }}

8. Jenis XSS & Cara Menanganinya

8.1 Stored XSS

  • Data disimpan di database
  • Ditampilkan ke user lain

➡ Solusi: Escape output di semua tempat render


8.2 Reflected XSS

  • Data langsung dari URL

➡ Solusi: Escape output


8.3 DOM-based XSS

  • Terjadi di JavaScript

➡ Solusi:

  • Hindari innerHTML
  • Gunakan textContent

9. Content Security Policy (CSP): Lapisan Proteksi Tambahan

Tambahkan header:

Content-Security-Policy: default-src 'self'

📌 CSP tidak menggantikan escaping, tapi membatasi dampak XSS.


10. Amankan Session & Cookie (XSS Related)

10.1 HttpOnly Cookie

session_set_cookie_params([
  'httponly' => true,
  'secure' => true
]);

👉 JavaScript tidak bisa mencuri session.


11. Gunakan ORM & Framework dengan Benar

Laravel, Symfony:

  • Default aman dari SQL Injection
  • Default auto-escape output

📌 Masalah muncul saat developer mem-bypass fitur keamanan.


12. Amankan API & AJAX Endpoint

❌ Jangan percaya JSON input
❌ Jangan expose error detail
❌ Validasi payload

📌 API juga target SQL Injection & XSS.


13. Logging & Monitoring Serangan

  • Log query error
  • Monitor payload aneh
  • Alert percobaan injection

📌 Serangan sering dicoba berulang kali.


14. Studi Kasus Nyata

Website Bisnis Lokal

Masalah:

  • Data user bocor
  • Deface halaman

Penyebab:

  • Query concat
  • Tidak escape output

Solusi:

  • Prepared statement
  • Output escaping global
  • CSP

Hasil:

  • Tidak ada insiden ulang
  • Audit keamanan lolos

15. Checklist PHP Security: SQL Injection & XSS

SQL Injection

✅ Prepared statement
✅ No string concat
✅ DB user privilege minimal

XSS

✅ Escape output
✅ CSP header
✅ HttpOnly cookie
✅ Hindari inline JS


16. Kesalahan Umum Developer PHP

❌ “Input sudah saya filter”
❌ “User internal aman”
❌ “Framework sudah handle semuanya”

📌 Keamanan bukan asumsi, tapi disiplin.


Kesimpulan

PHP aman dari SQL Injection & XSS jika digunakan dengan benar.

Masalah keamanan bukan soal bahasa pemrograman, tapi:

  • Cara menulis kode
  • Konsistensi
  • Awareness developer

Website yang aman bukan yang tidak pernah diserang, tapi yang tidak pernah berhasil ditembus.

Dengan menerapkan praktik di atas, Anda:

  • Melindungi data user
  • Menjaga reputasi bisnis
  • Menghindari kerugian besar