WAF (Web Application Firewall) adalah penyaring di depan aplikasi web: dia membaca setiap HTTP request, mencocokkannya dengan daftar pola serangan, lalu memblokir yang cocok sebelum sampai ke aplikasimu. Bayangin satpam di lobi gedung kantor yang memegang daftar barang terlarang. Tas yang berisi barang di daftar itu ditahan. Tapi satpam yang daftarnya terlalu luas juga menahan koki kantin yang membawa pisau dapur (salah tahan), dan satpam gak tahu apakah tamu boleh masuk ruang 12. Itu urusan kunci pintu ruangan, yaitu kode aplikasimu sendiri.
🧪 Tebakan cepat: di Lab, WAF memblokir semua request yang argumennya mengandung tanda kutip satu
'. Di log ada lima serangan klasik dan empat request sah. Berapa serangan yang tertangkap, dan siapa yang ikut terblokir? Jawabannya ada di bagian "Menguji rule ke log request".
Di mana WAF berdiri
Pengunjung -> WAF (baca request, cocokkan rule) -> Aplikasi
|
+-> cocok rule blokir: 403 Forbidden, request berhenti di sini
WAF bekerja di layer 7 (application layer): dia mengerti HTTP, jadi bisa membaca path, query, header dan body, bukan cuma alamat IP dan port seperti firewall server (UFW) di pelajaran sebelumnya. Ada dua bentuk yang umum:
- WAF terkelola di depan situsmu, seperti Cloudflare WAF atau AWS WAF. Kamu menyalakan managed rules (kumpulan rule siap pakai dari penyedia) dan menambah rule sendiri.
- WAF self-hosted: ModSecurity, WAF open-source yang jalan sebagai modul di Apache atau Nginx, biasanya dipakai bersama OWASP Core Rule Set (CRS), kumpulan rule untuk serangan umum.
Rule: cocokkan, lalu blokir atau catat
Satu rule berisi tiga bagian: bagian request yang dibaca, pola yang dicari, dan tindakan kalau cocok. Di ModSecurity:
SecRuleEngine On
SecRule ARGS "@contains OR 1=1" "id:1003,phase:2,deny,status:403,log,msg:'SQLi pattern'"
SecRule REQUEST_HEADERS:User-Agent "@contains sqlmap" "id:1007,phase:1,deny,status:403,log,msg:'Scanner'"
ARGSadalah nilai semua argumen request (query dan form).REQUEST_HEADERS:User-Agentadalah satu header.@containsmencari potongan teks. Ada juga@rxuntuk regex.deny,status:403menghentikan request dengan 403 Forbidden.logmencatatnya.idwajib unik untuk tiap rule.SecRuleEnginemengatur seluruh WAF:Onmemblokir,DetectionOnlycuma mencatat apa yang akan diblokir,Offmati.
DetectionOnly adalah mode monitoring: rule baru dijalankan dulu tanpa memblokir, supaya kamu bisa melihat request sah mana yang ikut cocok sebelum ada pengguna sungguhan yang ditolak.
Menguji rule ke log request
Di Lab ada sembilan request dari log. Lima serangan klasik, empat request sah:
| Request | Jenis |
|---|---|
GET /products?id=1 OR 1=1 -- |
serangan: SQL injection |
GET /search?q=<script>alert(1)</script> |
serangan: XSS |
GET /files?path=../../etc/passwd |
serangan: path traversal |
GET /ping?host=;cat /etc/passwd |
serangan: command injection |
GET /products?id=5 dengan User-Agent sqlmap |
serangan: scanner otomatis |
GET /search?q=O'Brien |
sah: nama orang |
GET /notes?text=beli susu; beli roti |
sah: catatan belanja |
GET /files?path=docs/panduan.pdf |
sah: unduh dokumen |
GET /ping?host=api.belajarweb.example |
sah: cek server |
Lab mulai dengan dua rule yang sering ditulis orang pertama kali: blokir argumen yang berisi ', dan blokir argumen yang berisi ;. Hasilnya:
| Rule | Serangan tertangkap | Request sah ikut terblokir |
|---|---|---|
argumen berisi ' |
0 | O'Brien |
argumen berisi ; |
command injection | beli susu; beli roti |
Rule tanda kutip menangkap nol serangan, karena gak ada satu pun dari lima serangan itu yang memakai kutip, dan malah memblokir orang bernama O'Brien. Itu jawaban tebakannya. Request sah yang terblokir disebut false positive. Serangan yang lolos disebut false negative. Dua-duanya sama penting: WAF yang memblokir pelanggan sama merugikannya dengan WAF yang membiarkan serangan.
Rule yang lebih tepat menyasar bentuk serangannya, atau malah menyebut bentuk yang boleh:
| Rule | Menangkap | False positive |
|---|---|---|
argumen berisi OR 1=1 |
SQL injection | 0 |
argumen berisi <script |
XSS | 0 |
argumen berisi ../ |
path traversal | 0 |
di /ping, host bukan hostname (^[a-z0-9.-]+$) |
command injection | 0 |
User-Agent berisi sqlmap |
scanner | 0 |
Rule /ping itu allowlist: dia gak menebak semua bentuk serangan, dia cuma mengizinkan huruf, angka, titik dan tanda minus untuk parameter yang memang berisi nama host. Lima rule ini menangkap kelima serangan dengan nol false positive.
Kenapa WAF bukan pengganti kode yang aman
Rule mencocokkan pola teks. Serangan yang ditulis dengan cara lain, artinya sama tapi teksnya beda, bisa gak cocok dengan pola itu. Itu yang disebut WAF bypass. WAF juga gak tahu logika aplikasimu: request GET /api/orders/124 dari user yang bukan pemilik pesanan itu terlihat normal, jadi WAF meloloskannya. Pengecekan seperti itu harus ada di kode.
Jadi WAF adalah lapisan tambahan (defense in depth): dia menahan serangan umum dan memberi waktu, sementara perlindungan utamanya tetap prepared statement, escape output, validasi input dan pengecekan hak akses di aplikasi.
⚠️ Jebakan yang sering ketemu
- Rule terlalu luas. Memblokir semua
'atau;menolak nama dan catatan biasa, sementara serangan yang sebenarnya belum tentu tertangkap. Uji rule ke log request sungguhan, hitung tangkapan dan false positive-nya. - Langsung
Ontanpa monitoring. Jalankan rule baru diDetectionOnlydulu, baca log-nya, baru blokir. - Mengira WAF cukup. WAF bisa di-bypass dan gak paham hak akses. Kode yang rentan tetap rentan di belakang WAF.
- Mematikan rule untuk seluruh situs karena satu false positive. Buat pengecualian sempit untuk parameter dan path itu saja.
TL;DR: WAF (Web Application Firewall) adalah penyaring di layer 7 yang membaca setiap HTTP request dan memblokir yang cocok dengan rule, contohnya Cloudflare WAF, AWS WAF, dan ModSecurity (open-source, modul Apache/Nginx) dengan OWASP CRS. Rule berisi bagian request, pola, dan tindakan (deny dengan 403, atau cuma log); SecRuleEngine DetectionOnly adalah mode monitoring sebelum On. Uji rule ke log: rule terlalu luas bikin false positive, rule yang tepat atau allowlist menangkap serangan tanpa mengganggu pengguna. WAF bisa di-bypass dan gak tahu logika aplikasi, jadi dia lapisan tambahan, bukan pengganti kode yang aman.