Mengaktifkan Brute Force Detection di realm, memperkuat security headers, melindungi sesi dan token dari pembajakan, serta menyusun rutinitas security auditing untuk menjaga Keycloak tetap aman di production.

Di episode 23 kalian memasang MFA di depan pintu autentikasi: TOTP, WebAuthn, dan recovery codes. Episode 24 ini melengkapi pertahanan dari sisi yang berbeda — melindungi pintu itu sendiri dari serangan brute force, lalu memperkuat area yang sering terlupakan: security headers, sesi, token, dan rutinitas audit keamanan. Kalau episode 22 membahas apa yang tercatat di log, episode ini membahas cara mencegah hal buruk terjadi sejak awal.
Brute force adalah serangan menebak kredensial dengan mencoba jutaan kombinasi password. Keycloak menyediakan mekanisme built-in bernama Brute Force Detection yang diaktifkan per realm lewat menu Realm Settings → Security Defenses → Brute Force Detection. Begitu diaktifkan, Keycloak mencatat setiap percobaan login yang gagal dan menahan autentikasi begitu jumlahnya melewati ambang.
Setiap kegagalan login menaikkan penghitung untuk user tersebut, dan Keycloak juga memisahkan penghitungan berdasarkan IP asal. Dua jenis lockout yang dihasilkan:
failureFactor tercapai; akun ditahan selama waitIncrementSeconds sebelum percobaan berikutnya diizinkan.maxFailureWaitSeconds, menciptakan efek lockout yang praktis permanen.Pengaturan kunci yang perlu kalian kuasai:
| Pengaturan | Fungsi |
|---|---|
failureFactor | jumlah percobaan gagal sebelum akun ditahan sementara |
waitIncrementSeconds | durasi penahanan, bertambah setiap percobaan lanjutan |
maxFailureWaitSeconds | batas atas penahanan, menciptakan efek lockout berkepanjangan |
maxDeltaTimeSeconds | jendela waktu percobaan gagal tetap dihitung |
quickLoginCheckMilliSeconds | jeda antar percobaan yang dianggap terlalu cepat |
minimumQuickLoginWaitSeconds | penalti tambahan untuk percobaan super cepat |
failureFactor adalah ambang paling penting: dengan nilai 5, akun ditahan sementara setelah lima percobaan gagal. waitIncrementSeconds menentukan durasi penahanan, dan nilainya naik setiap percobaan gagal berlanjut — sampai akhirnya maxFailureWaitSeconds menciptakan lockout berkepanjangan. Kombinasi inilah yang membuat penyerang kehabisan waktu sebelum sempat menebak.
Tip
Mulai dengan nilai moderat: failureFactor 5, waitIncrementSeconds 60, dan maxFailureWaitSeconds 900. Nilai terlalu agresif bisa mengunci user asli kalian saat ada script salah ketik password — dan melahirkan tiket helpdesk yang tidak perlu.
Keycloak menghitung percobaan gagal per user sekaligus per IP asal. Agar penghitungan per IP akurat, Keycloak harus mengenali alamat IP klien yang sebenarnya. Dengan reverse proxy di depan, yang terlihat adalah IP proxy — kecuali header X-Forwarded-For dipakai:
kc.sh start --proxy-headers xforwardedkc.sh start --proxy-headers xforwarded membuat Keycloak mempercayai header yang diteruskan proxy. Tanpa ini, serangan dari banyak IP dihitung seolah datang dari satu IP proxy yang sama, dan lockout per IP kehilangan maknanya.
Untuk lapisan tambahan, Keycloak punya langkah Insert CAPTCHA di flow autentikasi browser. Di menu Authentication → Flows, salin flow browser dengan tombol Copy, beri nama baru (misalnya browser captcha), lalu tambahkan eksekusi Insert CAPTCHA dan letakkan tepat setelah langkah Password. Saat pola mencurigakan terdeteksi, manusia bisa lewat dengan mengetik kode, sementara bot akan tersendat.
Keycloak mengirim sejumlah security headers secara default. Kalian tetap harus paham artinya, karena reverse proxy di depan bisa menimpa atau menambahkannya:
| Header | Fungsi |
|---|---|
| Content-Security-Policy | membatasi sumber resource yang boleh dimuat browser |
| X-Frame-Options | mencegah halaman Keycloak di-frame situs lain (clickjacking) |
| X-Content-Type-Options | mencegah browser menebak tipe konten (MIME sniffing) |
| Strict-Transport-Security | memaksa browser memakai HTTPS untuk domain ini |
| X-XSS-Protection | pertahanan lama terhadap reflected XSS, kini usang di browser modern |
Jika kebijakan default kurang ketat, perkuat di lapisan proxy — contoh NGINX:
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Catatan penting: X-XSS-Protection bukan pengganti CSP. Fokuskan upaya pada Content-Security-Policy yang benar, bukan header yang sudah banyak diabaikan browser.
Sesi adalah titik paling empuk: begitu sesi dibajak, penyerang menjelma menjadi user. Pertahanan berlapis:
Secure agar tidak bocor lewat HTTP, dan SameSite untuk membatasi pengiriman cookie lintas situs.HttpOnly, Secure, dan SameSite yang sesuai dengan arsitektur kalian.state untuk membuktikan request datang dari aplikasi yang sama; jangan pernah membuangnya.Token adalah identitas berjalan. Lindungi berlapis:
Semua kontrol di atas butuh penjagaan rutin, bukan sekali pasang lalu lupa:
Event admin dari episode 22 adalah bahan baku audit: gabungkan dengan percobaan login yang ditolak untuk melihat pola serangan lebih awal.
| Ancaman | Mitigasi |
|---|---|
| Brute force password | Brute Force Detection dengan failureFactor yang wajar |
| Serangan dari banyak IP | IP-based blocking berbasis X-Forwarded-For |
| Bot otomatis | CAPTCHA pada flow browser |
| Clickjacking | X-Frame-Options dan CSP yang ketat |
| Sesi dibajak | Cookie HttpOnly + Secure + SameSite, HTTPS |
| Token curian | Endpoint revoke, rotasi kunci, verifikasi signature |
| Kerentanan tak tertambal | Auditing rutin, patching, penetration test |
Episode 24 mengajarkan kalian menutup celah di lapisan paling dekat dengan penyerang: Brute Force Detection dengan failureFactor, waitIncrementSeconds, dan maxFailureWaitSeconds; IP-based blocking yang bergantung pada X-Forwarded-For; CAPTCHA di flow browser; security headers; keamanan sesi dan token; serta rutinitas auditing yang menjaga semuanya tetap segar.
Inti yang harus dibawa pulang:
maxFailureWaitSeconds membuat serangan tidak ekonomis.--proxy-headers xforwarded, semua perlindungan per IP jadi buta.Di episode 25 berikutnya, kalian beralih dari melindungi pintu masuk ke mengatur apa yang boleh dilakukan user di dalam: fine-grained authorization dengan Authorization Services Keycloak — menentukan akses per resource, bukan sekadar per role.