Keamanan Web Dasar: Jangan Pernah Percaya Input Pengguna
Halo Sobat Jurnal Coding! Saya masih ingat betul perasaan bangga yang luar biasa saat pertama kali berhasil membuat halaman login untuk website buatan saya sendiri. Rasanya saya sudah pantas disejajarkan dengan Mark Zuckerberg. Saya mengetikkan username, memasukkan password, mengeklik tombol "Masuk", dan voila! Halaman dasbor pun terbuka.
Namun, kebanggaan itu hancur berkeping-keping beberapa minggu kemudian saat seorang teman (yang kebetulan paham sedikit tentang keamanan web) berhasil masuk ke dasbor admin saya TANPA mengetahui password-nya sama sekali.
Saya panik setengah mati. Bagaimana mungkin dia bisa masuk? Apakah dia meretas server saya? Apakah dia menggunakan alat canggih ala film The Matrix?
Ternyata tidak. Dia hanya mengetikkan beberapa simbol aneh di kolom username, dan sistem saya langsung memberikan kunci pintu utama begitu saja. Kesalahan fatal yang saya lakukan saat itu adalah kesalahan yang paling sering dilakukan oleh 99% web developer pemula: Saya terlalu percaya pada pengguna.
### Hukum Emas Pemrograman: Jangan Pernah Percaya Siapapun
Di dunia nyata, jika kamu menjadi penjaga pintu sebuah acara eksklusif, kamu tidak akan langsung mengizinkan seseorang masuk hanya karena dia memakai jas rapi dan mengaku bernama "Budi". Kamu pasti akan meminta KTP-nya, mencocokkannya dengan daftar tamu, dan memastikan KTP itu asli.
Sayangnya, saat pertama kali belajar membuat website, kita sering menganggap bahwa kotak input (seperti kolom pencarian, kolom komentar, atau form login) hanya akan diisi dengan data yang "normal". Kita berasumsi jika kita meminta "Nama", pengunjung akan mengetikkan nama mereka.
Kenyataannya, internet adalah hutan belantara yang buas. Ada banyak orang usil (dan peretas otomatis/bot) di luar sana yang tidak akan mengetikkan nama mereka. Alih-alih mengetik "Andi", mereka mungkin akan mengetikkan sebuah kode rahasia yang dirancang khusus untuk menghancurkan, mencuri, atau memanipulasi database kamu.
Serangan paling legendaris, paling mematikan, dan paling umum dari celah ini bernama SQL Injection (Suntikan SQL).
### Apa Itu SQL Injection?
Bayangkan database kamu adalah seorang pelayan gudang yang sangat patuh namun sangat lugu. Setiap kali ada pengunjung yang login, sistem PHP kamu akan menyuruh pelayan gudang ini: "Hei Pelayan, tolong periksa apakah ada pengguna bernama [Nama Yang Diketik] dan password [Password Yang Diketik]."
Dalam kode PHP yang rentan (dan sering diajarkan di tutorial lawas), kodenya akan terlihat seperti ini:
// CONTOH KODE BURUK (JANGAN DITIRU!)
$username = $_POST["username"];
$password = $_POST["password"];
// Menggabungkan teks ketikan pengguna langsung ke dalam perintah SQL
$query = "SELECT * FROM pengguna WHERE username = "" . $username . "" AND password = "" . $password . """;
$koneksi->query($query);
Lalu, apa yang terjadi jika si peretas tidak mengetikkan nama "Andi", melainkan mengetikkan teks ajaib ini di kolom username: " atau ""="
Pelayan gudang kamu yang lugu tadi akan membaca perintahnya menjadi seperti ini: "Tolong cari pengguna bernama kosong ATAU yang mana kosong sama dengan kosong". Karena pernyataan "kosong sama dengan kosong" selalu bernilai BENAR (True) di dalam matematika, pelayan gudang ini akan langsung membuka pintu brankas dan berkata, "Ah, ternyata benar! Silakan masuk!"
Bum! Website kamu resmi diretas. Peretas berhasil melewati form login tanpa menebak password sama sekali.
### Solusi Elegan: Gunakan Prepared Statements
Kamu tidak perlu mematikan website kamu dan kembali ke zaman batu untuk mengatasi masalah ini. Cara paling modern dan profesional untuk mencegah SQL Injection adalah dengan menggunakan metode yang disebut Prepared Statements (Pernyataan yang Disiapkan).
Kembali ke analogi penjaga pintu. Daripada membiarkan pengunjung berbicara langsung dengan si pelayan gudang, kita menyiapkan "kotak cetakan" khusus. Pengunjung hanya boleh memasukkan barang ke dalam kotak cetakan itu. Sistem tidak akan pernah membaca isi kotak itu sebagai "perintah", melainkan hanya membacanya murni sebagai "teks biasa".
Jika mereka memasukkan kode retasan, sistem hanya akan menganggap itu sebagai orang aneh yang memiliki nama "kode retasan", dan tentu saja nama tersebut tidak ada di database.
Berikut adalah cara penulisan kode PHP modern yang 100% kebal dari SQL Injection:
// CONTOH KODE AMAN (PREPARED STATEMENTS)
$username = $_POST["username"];
$password = $_POST["password"];
// 1. Siapkan cetakan perintahnya (Gunakan tanda tanya ? sebagai tempat kosong)
$stmt = $koneksi->prepare("SELECT * FROM pengguna WHERE username = ? AND password = ?");
// 2. Masukkan input pengguna ke dalam tempat kosong tadi secara aman
// Huruf "ss" berarti kita memasukkan dua data bertipe String (teks)
$stmt->bind_param("ss", $username, $password);
// 3. Jalankan perintahnya
$stmt->execute();
$hasil = $stmt->get_result();
Melihat perbedaan kode di atas, kamu mungkin berpikir, "Wah, kodenya jadi lebih panjang ya?"
Memang benar, kode yang aman selalu membutuhkan beberapa baris ekstra. Namun, percayalah, menulis tiga baris tambahan hari ini jauh lebih baik daripada harus menangis kehilangan seluruh data website yang sudah kamu bangun berbulan-bulan akibat diretas oleh anak SMP iseng.
### Kesimpulan: Keamanan adalah Sebuah Pola Pikir
Menjadi programmer yang baik bukan hanya tentang membuat tombol bisa diklik atau membuat warna website menjadi cantik. Menjadi programmer profesional berarti kamu selalu berpikir paranoid (dalam konotasi positif).
Mulai hari ini, jadikan ini sebagai prinsip sucimu: Jangan pernah percaya pada apapun yang diketik oleh pengguna. Entah itu kolom pendaftaran, formulir kontak, atau kolom pencarian. Selalu saring, bersihkan, dan gunakan Prepared Statements saat berbicara dengan database-mu.
Selamat mencoba, dan mari buat internet menjadi tempat yang lebih aman!
Namun, kebanggaan itu hancur berkeping-keping beberapa minggu kemudian saat seorang teman (yang kebetulan paham sedikit tentang keamanan web) berhasil masuk ke dasbor admin saya TANPA mengetahui password-nya sama sekali.
Saya panik setengah mati. Bagaimana mungkin dia bisa masuk? Apakah dia meretas server saya? Apakah dia menggunakan alat canggih ala film The Matrix?
Ternyata tidak. Dia hanya mengetikkan beberapa simbol aneh di kolom username, dan sistem saya langsung memberikan kunci pintu utama begitu saja. Kesalahan fatal yang saya lakukan saat itu adalah kesalahan yang paling sering dilakukan oleh 99% web developer pemula: Saya terlalu percaya pada pengguna.
### Hukum Emas Pemrograman: Jangan Pernah Percaya Siapapun
Di dunia nyata, jika kamu menjadi penjaga pintu sebuah acara eksklusif, kamu tidak akan langsung mengizinkan seseorang masuk hanya karena dia memakai jas rapi dan mengaku bernama "Budi". Kamu pasti akan meminta KTP-nya, mencocokkannya dengan daftar tamu, dan memastikan KTP itu asli.
Sayangnya, saat pertama kali belajar membuat website, kita sering menganggap bahwa kotak input (seperti kolom pencarian, kolom komentar, atau form login) hanya akan diisi dengan data yang "normal". Kita berasumsi jika kita meminta "Nama", pengunjung akan mengetikkan nama mereka.
Kenyataannya, internet adalah hutan belantara yang buas. Ada banyak orang usil (dan peretas otomatis/bot) di luar sana yang tidak akan mengetikkan nama mereka. Alih-alih mengetik "Andi", mereka mungkin akan mengetikkan sebuah kode rahasia yang dirancang khusus untuk menghancurkan, mencuri, atau memanipulasi database kamu.
Serangan paling legendaris, paling mematikan, dan paling umum dari celah ini bernama SQL Injection (Suntikan SQL).
### Apa Itu SQL Injection?
Bayangkan database kamu adalah seorang pelayan gudang yang sangat patuh namun sangat lugu. Setiap kali ada pengunjung yang login, sistem PHP kamu akan menyuruh pelayan gudang ini: "Hei Pelayan, tolong periksa apakah ada pengguna bernama [Nama Yang Diketik] dan password [Password Yang Diketik]."
Dalam kode PHP yang rentan (dan sering diajarkan di tutorial lawas), kodenya akan terlihat seperti ini:
// CONTOH KODE BURUK (JANGAN DITIRU!)
$username = $_POST["username"];
$password = $_POST["password"];
// Menggabungkan teks ketikan pengguna langsung ke dalam perintah SQL
$query = "SELECT * FROM pengguna WHERE username = "" . $username . "" AND password = "" . $password . """;
$koneksi->query($query);
Lalu, apa yang terjadi jika si peretas tidak mengetikkan nama "Andi", melainkan mengetikkan teks ajaib ini di kolom username: " atau ""="
Pelayan gudang kamu yang lugu tadi akan membaca perintahnya menjadi seperti ini: "Tolong cari pengguna bernama kosong ATAU yang mana kosong sama dengan kosong". Karena pernyataan "kosong sama dengan kosong" selalu bernilai BENAR (True) di dalam matematika, pelayan gudang ini akan langsung membuka pintu brankas dan berkata, "Ah, ternyata benar! Silakan masuk!"
Bum! Website kamu resmi diretas. Peretas berhasil melewati form login tanpa menebak password sama sekali.
### Solusi Elegan: Gunakan Prepared Statements
Kamu tidak perlu mematikan website kamu dan kembali ke zaman batu untuk mengatasi masalah ini. Cara paling modern dan profesional untuk mencegah SQL Injection adalah dengan menggunakan metode yang disebut Prepared Statements (Pernyataan yang Disiapkan).
Kembali ke analogi penjaga pintu. Daripada membiarkan pengunjung berbicara langsung dengan si pelayan gudang, kita menyiapkan "kotak cetakan" khusus. Pengunjung hanya boleh memasukkan barang ke dalam kotak cetakan itu. Sistem tidak akan pernah membaca isi kotak itu sebagai "perintah", melainkan hanya membacanya murni sebagai "teks biasa".
Jika mereka memasukkan kode retasan, sistem hanya akan menganggap itu sebagai orang aneh yang memiliki nama "kode retasan", dan tentu saja nama tersebut tidak ada di database.
Berikut adalah cara penulisan kode PHP modern yang 100% kebal dari SQL Injection:
// CONTOH KODE AMAN (PREPARED STATEMENTS)
$username = $_POST["username"];
$password = $_POST["password"];
// 1. Siapkan cetakan perintahnya (Gunakan tanda tanya ? sebagai tempat kosong)
$stmt = $koneksi->prepare("SELECT * FROM pengguna WHERE username = ? AND password = ?");
// 2. Masukkan input pengguna ke dalam tempat kosong tadi secara aman
// Huruf "ss" berarti kita memasukkan dua data bertipe String (teks)
$stmt->bind_param("ss", $username, $password);
// 3. Jalankan perintahnya
$stmt->execute();
$hasil = $stmt->get_result();
Melihat perbedaan kode di atas, kamu mungkin berpikir, "Wah, kodenya jadi lebih panjang ya?"
Memang benar, kode yang aman selalu membutuhkan beberapa baris ekstra. Namun, percayalah, menulis tiga baris tambahan hari ini jauh lebih baik daripada harus menangis kehilangan seluruh data website yang sudah kamu bangun berbulan-bulan akibat diretas oleh anak SMP iseng.
### Kesimpulan: Keamanan adalah Sebuah Pola Pikir
Menjadi programmer yang baik bukan hanya tentang membuat tombol bisa diklik atau membuat warna website menjadi cantik. Menjadi programmer profesional berarti kamu selalu berpikir paranoid (dalam konotasi positif).
Mulai hari ini, jadikan ini sebagai prinsip sucimu: Jangan pernah percaya pada apapun yang diketik oleh pengguna. Entah itu kolom pendaftaran, formulir kontak, atau kolom pencarian. Selalu saring, bersihkan, dan gunakan Prepared Statements saat berbicara dengan database-mu.
Selamat mencoba, dan mari buat internet menjadi tempat yang lebih aman!