DNS RobotDNS Propagation Checker
BerandaDNSWHOISIPSSL
DNS RobotDNS Propagation Checker

Alat pemeriksaan DNS generasi terbaru

Kebijakan PrivasiKetentuan LayananTentang KamiBlogKontak

Alat DNS

Pencarian DNSTes Kecepatan DNSDomain ke IPPencarian NSPencarian MXLihat semua

Alat Email

Pemeriksa Rekaman SPFPemeriksa DMARCPemeriksa DKIMAlat Tes SMTPAnalisis Header EmailLihat semua

Alat Website

Pencarian WHOISCek Hosting WebsiteKetersediaan DomainPencari SubdomainPendeteksi CMSLihat semua

Alat Jaringan

Alat PingTraceroutePemeriksa PortPemeriksaan Header HTTPPemeriksaan Sertifikat SSLLihat semua

Alat IP

Pencarian IPIP Saya ApaPemeriksaan Daftar Hitam IPIP ke HostnamePencarian ASNLihat semua

Alat Utilitas

Pemindai QR CodePembuat QR CodeUPI QR Code GeneratorWiFi QR Code GeneratorPenerjemah Kode MorseLihat semua
© 2026 DNS Robot. Dikembangkan oleh: ❤ Shaik Brothers
Semua sistem beroperasi normal
Made with
Beranda/Blog/Keamanan Website: Praktik Terbaik Lapis demi Lapis (2026)

Keamanan Website: Praktik Terbaik Lapis demi Lapis (2026)

Shaik Vahid29 Sep 202630 menit baca
Keamanan website dalam enam lapisan: domain dan DNS, TLS, header HTTP, aplikasi, dependensi, dan server
Keamanan website dalam enam lapisan: domain dan DNS, TLS, header HTTP, aplikasi, dependensi, dan server

Poin Penting

Keamanan website yang efektif dibangun berlapis: kunci domain dan DNS (registrar lock, DNSSEC, CAA), wajibkan TLS modern dengan HSTS, kirim serangkaian HTTP security header yang ketat, hash kata sandi dengan Argon2id yang dilengkapi MFA dan rate limit, validasi input serta terapkan kontrol akses di server, pin dan audit dependensi, tutup setiap port yang tidak Anda layani, dan simpan log yang cukup untuk menyadari adanya pembobolan. Setiap praktik di bawah ini disertai konfigurasi persisnya dan cara gratis untuk memverifikasi bahwa praktik itu benar-benar berjalan, karena kontrol yang belum pernah diuji sama saja dengan kontrol yang tidak Anda miliki.

Advertisement

Apa Itu Praktik Terbaik Keamanan Website?

Praktik terbaik keamanan website adalah serangkaian kontrol yang menjaga website atau aplikasi web agar tidak diambil alih, di-deface, dipakai untuk menyerang pengunjungnya sendiri, atau datanya dikuras diam-diam. Praktik ini bukan satu produk atau satu pengaturan. Ini adalah tumpukan keputusan yang dimulai dari registrar domain, lalu berlanjut ke DNS, TLS, header HTTP yang dikirim server Anda, kode yang menangani login dan input, paket pihak ketiga yang menjadi fondasi aplikasi Anda, server itu sendiri, dan terakhir log yang memberi tahu Anda ketika ada yang tidak beres.

Alasan berpikir dalam lapisan sederhana saja: penyerang juga berpikir begitu. Data Breach Investigations Report 2026 dari Verizon menemukan bahwa 31% pembobolan kini berawal dari kerentanan software yang dieksploitasi, yang untuk pertama kalinya mengalahkan kredensial curian sebagai jalan masuk paling umum, dan bahwa 48% dari seluruh pembobolan melibatkan ransomware. Satu patch yang terlewat, satu API key yang bocor, atau satu halaman admin tanpa rate limiting sudah cukup. Tidak ada kontrol dalam panduan ini yang eksotis; website yang dibobol biasanya adalah website yang melewatkan hal-hal dasar di satu lapisan sambil sibuk memoles lapisan lain.

Panduan ini disusun dari luar ke dalam. Setiap praktik menjelaskan mengapa praktik itu penting, apa persisnya yang harus dikonfigurasi, dan cara memverifikasinya dengan sebuah perintah atau alat gratis, karena kegagalan paling umum yang kami lihat dalam pemeriksaan header HTTP dan pemeriksaan SSL bukanlah keputusan yang buruk, melainkan pengaturan yang diyakini sudah aktif tetapi tidak pernah dipastikan.

Catatan

Jika Anda hanya punya waktu satu jam: aktifkan registrar lock dan MFA di registrar, wajibkan HTTPS dengan HSTS, tambahkan security header dari tabel di Lapisan 3, hash kata sandi dengan Argon2id, perbarui setiap dependensi yang memiliki CVE yang sudah diketahui, dan tutup semua port kecuali 80 dan 443. Langkah-langkah itu menutup titik masuk di balik sebagian besar pembobolan website di dunia nyata.

Tumpukan Keamanan Web: Enam Lapisan yang Harus Dilindungi

Setiap serangan terhadap website mendarat di salah satu dari enam lapisan. Tabel di bawah ini adalah peta untuk sisa panduan ini: apa yang ada di setiap lapisan, bagaimana lapisan itu biasanya diserang, dan pemeriksaan gratis mana yang memastikan pertahanan Anda benar-benar terpasang.

LapisanYang dilakukan penyerang di siniPraktik utamaVerifikasi dengan
1. Domain dan DNSMembajak domain, mengubah nameserver, mengambil alih subdomain yang menggantung (dangling), mendapatkan sertifikat palsuRegistrar lock, MFA, DNSSEC, CAA, audit record usangPencarian WHOIS, Pencarian DNS, Pencari Subdomain
2. Transport (TLS)Menurunkan koneksi ke HTTP (downgrade), melucuti enkripsi, mengeksploitasi cipher lama, sertifikat kedaluwarsaTLS 1.2+, HSTS dengan preload, perpanjangan otomatisPemeriksaan Sertifikat SSL
3. Header HTTPMenyisipkan skrip (XSS), membingkai situs untuk clickjacking, menebak (sniffing) tipe konten, membocorkan referrerCSP, frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyPemeriksaan Header HTTP
4. AplikasiCredential stuffing, injection, kontrol akses yang rusak (broken access control), CSRF, upload yang tidak amanArgon2id + MFA + rate limit, query berparameter, otorisasi di sisi server, cookie SameSiteCode review, OWASP ZAP, Penguji Kekuatan Kata Sandi
5. DependensiPaket yang diracuni, CVE yang sudah diketahui di library, pipeline CI yang disusupiLockfile, audit, versi yang di-pin, SBOM, token dengan hak akses minimumnpm audit, Dependabot, Trivy
6. Server dan operasionalPort terbuka, kredensial default, patch yang terlewat, tanpa backup, tanpa logFirewall, SSH hanya dengan kunci, patching, backup 3-2-1, logging terpusatPemeriksa Port, Pemeriksaan Daftar Hitam IP, Pemeriksa Kesehatan Domain

Tips

Kerjakan dari atas ke bawah. Lapisan 1 sampai 3 adalah konfigurasi yang bisa Anda selesaikan dalam satu sore, dan langsung melindungi semua halaman sekaligus. Lapisan 4 sampai 6 adalah kebiasaan berkelanjutan yang perlu menjadi bagian dari proses code review dan deployment Anda.

Advertisement

Lapisan 1: Kunci Domain dan DNS

Semua hal lain dalam panduan ini berasumsi Anda masih menguasai domain Anda. Jika penyerang bisa login ke registrar Anda atau mengubah nameserver, mereka bisa mengarahkan trafik Anda ke mana saja, mendapatkan sertifikat yang valid atas nama domain Anda, dan membaca setiap email yang dikirim kepada Anda, tanpa satu baris pun kode aplikasi Anda sempat berjalan. Karena itu, keamanan domain dan DNS adalah praktik terbaik keamanan website yang pertama, dan hampir seluruhnya berupa konfigurasi.

Mulailah dengan pencarian WHOIS pada domain Anda sendiri dan pastikan tiga hal: kode statusnya mencakup clientTransferProhibited, tanggal kedaluwarsanya masih lebih dari setahun lagi, dan registrarnya memang registrar tempat Anda punya akun. Cukup sering domain bisnis ternyata masih berada di akun registrar milik mantan kontraktor. Panduan pencarian WHOIS kami menjelaskan setiap kode status yang akan Anda temui.

Registrar Lock, MFA, dan Pengingat Masa Berlaku

Aktifkan registrar lock (disebut juga transfer lock) agar domain tidak bisa dipindahkan ke registrar lain tanpa Anda membukanya secara eksplisit, lalu aktifkan autentikasi multi-faktor (MFA) pada akun registrar itu sendiri. Akun registrar adalah sasaran phishing favorit justru karena satu login mengendalikan semua yang ada di bawahnya. Gunakan kunci keamanan fisik (hardware key) atau aplikasi autentikator, bukan SMS, di mana pun registrar mengizinkannya.

Atur domain agar diperpanjang otomatis dengan metode pembayaran yang tidak akan kedaluwarsa, dan tetap pasang pengingat kalender 60 hari sebelum tanggal kedaluwarsa. Domain yang kedaluwarsa disambar drop-catcher dalam hitungan jam, dan pembelinya mewarisi email Anda, trafik Anda, serta login OAuth apa pun yang memercayai domain Anda.

  • Registry lock (penguncian manual di tingkat registry yang dilakukan lewat jalur terpisah/out-of-band) layak dibayar lebih untuk domain yang menjadi tumpuan bisnis; penguncian ini mencegah perubahan nameserver bahkan jika akun registrar berhasil dibobol.

  • Pisahkan perannya. Orang yang membayar domain, akun yang memilikinya, dan penyedia DNS masing-masing harus terdokumentasi dan tidak terikat pada kotak surat satu karyawan.

  • Aktifkan privasi WHOIS agar detail kontak Anda tidak menjadi peta bagi pelaku phishing, dan gunakan alamat peran yang dipantau, seperti domains@, pada akun tersebut.

Tandatangani Zona dengan DNSSEC

DNSSEC menandatangani zona DNS Anda sehingga resolver bisa mendeteksi jawaban palsu. Tanpanya, penyerang yang mampu meracuni cache resolver bisa mengirim pengunjung Anda ke server palsu, sementara browser mereka tetap menampilkan nama domain Anda. Sebagian besar penyedia DNS terkelola (Cloudflare, Route 53, Google Cloud DNS, dan banyak registrar) mengaktifkannya cukup dengan satu tombol; satu-satunya langkah manual adalah memublikasikan record DS di registrar Anda. Verifikasi dengan dig, atau dengan pemeriksaan DNSSEC di dalam Pemeriksa Kesehatan Domain:

bash
dig +dnssec +short yourdomain.com A
# A signed zone returns the record AND an RRSIG line:
# 203.0.113.10
# A 13 2 3600 20261015000000 20260924000000 34505 yourdomain.com. Kx3f...==

dig +short yourdomain.com DS
# A DS record at the parent zone proves the chain of trust is complete
# 34505 13 2 6A1B...C9

Batasi Penerbitan Sertifikat dengan CAA

Record CAA (RFC 8659) memberi tahu otoritas sertifikat (CA) mana saja yang boleh menerbitkan sertifikat untuk domain Anda. Setiap CA publik wajib memeriksanya sebelum menerbitkan sertifikat, sehingga record CAA menutup pintu bagi penyerang yang berhasil mengelabui validasi domain di CA lain. Tiga record sudah mencakup kasus umum: siapa yang boleh menerbitkan, siapa yang boleh menerbitkan sertifikat wildcard, dan ke mana permintaan yang ditolak harus dilaporkan:

dns
yourdomain.com.  CAA 0 issue "letsencrypt.org"
yourdomain.com.  CAA 0 issuewild ";"
yourdomain.com.  CAA 0 iodef "mailto:security@yourdomain.com"

Peringatan

Sebelum menambahkan CAA, catat setiap CA yang saat ini menerbitkan sertifikat untuk Anda, termasuk CA di balik CDN atau panel hosting Anda (Cloudflare bergantian memakai beberapa CA; banyak host memakai Sectigo atau Let's Encrypt). Record CAA yang tidak mencantumkan CA Anda yang sebenarnya akan diam-diam menggagalkan perpanjangan berikutnya. Periksa penerbit saat ini dengan Pemeriksaan Sertifikat SSL terlebih dahulu.

Audit Record Usang: Subdomain Takeover

Subdomain takeover terjadi ketika sebuah record DNS masih mengarah ke layanan yang sudah tidak Anda gunakan: CNAME ke situs GitHub Pages yang sudah dihapus, aplikasi Azure, bucket S3, atau hostname milik vendor SaaS. Siapa pun bisa mendaftarkan target yang ditinggalkan itu lalu menyajikan konten di old-app.yourdomain.com atas nama Anda, lengkap dengan sertifikat yang valid. Ini salah satu temuan paling umum di program bug bounty karena tidak ada yang ingat record itu masih ada.

Jalankan domain Anda melalui Pencari Subdomain, yang membaca log certificate transparency, sehingga Anda melihat setiap hostname yang pernah diterbitkan sertifikatnya. Lalu resolve masing-masing dengan pencarian DNS dan hapus setiap record yang targetnya mengembalikan NXDOMAIN atau halaman "no such app" dari penyedia layanan. Ulangi setiap kuartal, dan jadikan penghapusan record DNS bagian dari proses penonaktifan layanan apa pun.

Tips

Certificate transparency juga merupakan sistem peringatan dini Anda: Cert Spotter dan pemantauan CT milik Cloudflare bisa mengirim email setiap kali ada CA yang menerbitkan sertifikat untuk domain Anda. Sertifikat yang tidak terduga sering kali menjadi tanda pertama yang terlihat dari pembobolan DNS atau registrar.

Lapisan 2: HTTPS dan TLS yang Dikonfigurasi dengan Benar

HTTPS bukan lagi sekadar praktik terbaik; HTTPS adalah standar minimum, dan browser menandai halaman HTTP biasa sebagai "Tidak aman". Yang masih membedakan situs yang aman dari situs yang sekadar terenkripsi adalah versi TLS yang Anda terima, apakah HTTP masih bisa dipakai untuk menjangkau Anda sama sekali, dan apakah perpanjangan sertifikat sudah cukup otomatis untuk bertahan menghadapi pemangkasan masa berlaku sertifikat yang dimulai pada Maret 2026.

Advertisement

Minimal TLS 1.2, Utamakan TLS 1.3

TLS 1.0 dan 1.1 secara resmi dinyatakan usang (deprecated) oleh RFC 8996 pada 2021, dan tidak ada browser saat ini yang masih menegosiasikannya. Nonaktifkan keduanya di server, utamakan TLS 1.3 (yang membuang semua cipher yang diketahui lemah dan menyelesaikan handshake dalam satu kali round trip), dan pertahankan TLS 1.2 hanya dengan cipher suite AEAD seperti ECDHE-ECDSA-AES128-GCM-SHA256 atau ECDHE-RSA-CHACHA20-POLY1305.

Ada dua baris yang penting saat Anda menguji dari luar: protokol yang dinegosiasikan, dan Verify return code: 0, yang berarti seluruh rantai sertifikat berhasil divalidasi. Sertifikat intermediate yang hilang adalah penyebab paling umum laporan "jalan di Chrome, gagal di curl dan Android"; panduan kami tentang rantai sertifikat SSL menunjukkan cara memperbaikinya, dan Pemeriksaan Sertifikat SSL langsung menandai rantai yang tidak lengkap. Berikut pemeriksaan yang dijalankan terhadap dnsrobot.net:

bash
echo | openssl s_client -connect dnsrobot.net:443 -servername dnsrobot.net 2>/dev/null \
  | grep -E 'Protocol|Cipher|Verify return'

# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384
# Verify return code: 0 (ok)

# Confirm the old versions are refused:
openssl s_client -connect dnsrobot.net:443 -tls1_1 2>&1 | grep -iE 'alert|no protocols'

Catatan

Daftar cipher adalah bagian yang paling cepat usang pada konfigurasi hasil salin-tempel. Daripada menulisnya sendiri, buat blok server yang saat ini direkomendasikan untuk nginx, Apache, Caddy, atau HAProxy dengan Mozilla SSL Configuration Generator dan pilih profil "Intermediate", kecuali Anda harus mendukung klien yang sangat lama.

HSTS: Jangan Biarkan Browser Memakai HTTP Lagi

Mengalihkan HTTP ke HTTPS saja tidak cukup. Permintaan pertama yang dibuat pengunjung ke http://yourdomain.com tetap dikirim dalam teks biasa, dan penyerang di jaringan yang sama bisa menjawabnya lebih dulu sebelum redirect Anda. HTTP Strict Transport Security (RFC 6797) mengatasi masalah ini: begitu browser pernah melihat header tersebut, browser akan menulis ulang setiap URL http:// untuk domain Anda menjadi https:// sebelum mengirim apa pun.

Gunakan max-age minimal satu tahun (31536000 detik), tambahkan includeSubDomains setelah semua subdomain melayani HTTPS, lalu daftarkan domain di hstspreload.org agar domain Anda tertanam langsung (hard-coded) di Chrome, Firefox, Safari, dan Edge. Preload menutup celah kunjungan pertama sepenuhnya. Verifikasi header ini dengan Pemeriksaan Header HTTP, yang menilai HSTS sebagai bagian dari skor keamanan A sampai F.

http
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Peringatan

HSTS adalah pintu satu arah. Begitu includeSubDomains masuk daftar preload, subdomain apa pun yang tidak bisa melayani HTTPS yang valid, termasuk tool internal dan host dev. yang terlupakan, tidak bisa lagi diakses dari browser. Terapkan secara bertahap: max-age=300 selama seminggu, lalu sebulan, lalu setahun, dan baru setelah itu tambahkan preload.

Sertifikat 47 Hari: Otomatiskan Perpanjangan Sekarang

Ballot SC-081 dari CA/Browser Forum memangkas masa berlaku maksimum setiap sertifikat TLS publik secara bertahap. Pemangkasan pertama berlaku sejak 15 Maret 2026, sehingga sertifikat apa pun yang Anda beli atau perpanjang hari ini sudah dibatasi 200 hari, dan pada 2029 sertifikat perlu diganti kira-kira setiap enam minggu:

Tanggal berlakuMasa berlaku maksimum sertifikatPenggunaan ulang validasi domain
Sebelum 15 Maret 2026398 hari398 hari
15 Maret 2026200 hari200 hari
15 Maret 2027100 hari100 hari
15 Maret 202947 hari10 hari

Perpanjangan manual tidak akan sanggup mengikuti jadwal ini. Praktik terbaiknya adalah penerbitan yang sepenuhnya otomatis melalui ACME: Let's Encrypt atau Google Trust Services lewat certbot, acme.sh, Caddy, atau sertifikat otomatis bawaan Cloudflare, Vercel, Netlify, dan sebagian besar panel hosting. Uji jalur perpanjangan sebelum Anda membutuhkannya (certbot renew --dry-run untuk certbot); kegagalan yang perlu diwaspadai adalah record CAA atau aturan firewall yang ditambahkan sejak perpanjangan terakhir dan kini memblokir validasi. Apa pun yang Anda gunakan, pantau juga tanggal kedaluwarsa dari luar: Pemeriksaan Sertifikat SSL menampilkan sisa hari, dan sertifikat yang kedaluwarsa mengubah setiap kunjungan menjadi peringatan browser satu halaman penuh.

Lapisan 3: Header Keamanan HTTP (Security Headers)

Security header adalah instruksi yang diberikan server kepada browser tentang apa yang boleh dan tidak boleh dilakukan terhadap halaman Anda: skrip mana yang boleh berjalan, apakah halaman boleh dibingkai (frame), apakah browser boleh menebak tipe konten, dan apa yang perlu diberitahukan ke situs lain tentang asal pengunjung. Header ini gratis, berlaku untuk semua halaman sekaligus, dan memblokir seluruh kelas serangan. Header juga merupakan lapisan yang paling sering dikonfigurasi setengah benar oleh kebanyakan situs, itulah sebabnya Pemeriksaan Header HTTP memberi nilai untuknya. Berikut header yang dikirim dnsrobot.net, dipangkas hanya pada security header:

bash
curl -sI https://dnsrobot.net/ | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'

strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' ... https://*.googletagmanager.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(self), microphone=(), geolocation=(), payment=(), usb=()

Tujuh Header yang Wajib Dikirim Setiap Situs

Inilah nilai yang perlu Anda tuju untuk situs pada umumnya. Lima yang pertama adalah yang memengaruhi nilai Anda; dua yang terakhir adalah tambahan murah setelah yang lain terpasang.

HeaderNilai yang direkomendasikanYang dicegah
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadDowngrade protokol, pencurian cookie melalui HTTP
Content-Security-Policyscript-src berbasis nonce dengan 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'Cross-site scripting (XSS), injeksi data, clickjacking
X-Content-Type-OptionsnosniffMIME sniffing yang mengubah file upload menjadi skrip yang bisa dieksekusi
Referrer-Policystrict-origin-when-cross-originBocornya URL lengkap (token, kata kunci pencarian) ke pihak ketiga
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Skrip pihak ketiga yang diam-diam memakai API browser yang sensitif
X-Frame-OptionsDENY (fallback lama untuk frame-ancestors)Clickjacking di browser tanpa CSP Level 2
Cross-Origin-Opener-Policysame-originSerangan lintas jendela melalui window.opener

Content Security Policy Tanpa Merusak Situs

Content Security Policy adalah pertahanan paling efektif terhadap XSS karena mencegah skrip sisipan berjalan bahkan ketika ada bug injeksi. Masalahnya, kebijakan yang ketat akan merusak skrip inline atau tag pihak ketiga yang terlupakan. Pendekatan modern, yang direkomendasikan Google dan didokumentasikan di MDN, adalah kebijakan berbasis nonce: server membuat nonce acak untuk setiap respons, memasangnya pada setiap tag script yang memang sengaja dirender, dan browser menolak semua yang lain.

'strict-dynamic' adalah yang membuat kebijakan ini praktis: skrip yang memiliki nonce boleh memuat skrip lain (analitik, tag manager, widget) tanpa harus memasukkan masing-masing ke allowlist, sementara token https: dan 'unsafe-inline' diabaikan oleh browser modern dan hanya berfungsi sebagai fallback untuk browser lama. Terapkan dulu dengan Content-Security-Policy-Report-Only, pantau laporan pelanggaran selama seminggu, lalu beralih ke mode enforce. Framework seperti Next.js, Rails, dan Django punya dukungan nonce bawaan; situs statis bisa memakai script-src berbasis hash sebagai gantinya.

http
Content-Security-Policy:
  script-src 'nonce-r4nd0m1z3dV4lu3' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'none';
  form-action 'self';
  report-to csp-endpoint

<!-- Only scripts carrying the nonce run; strict-dynamic lets them load their own dependencies -->
<script nonce="r4nd0m1z3dV4lu3" src="/app.js"></script>

Catatan

Kebijakan allowlist seperti script-src 'self' https://cdn.example.com lebih baik daripada tidak ada sama sekali, tetapi endpoint JSONP atau library lama apa pun di host yang masuk allowlist bisa dipakai untuk menembusnya. Jika Anda belum bisa memakai nonce, setidaknya atur object-src 'none' dan base-uri 'none', yang langsung menutup dua celah bypass yang umum.

Clickjacking: frame-ancestors dan X-Frame-Options

Clickjacking memuat situs Anda secara tak terlihat di dalam halaman penyerang dan mengelabui pengunjung agar mengklik tombol yang tidak bisa mereka lihat. frame-ancestors 'none' di CSP (atau 'self' jika Anda menyematkan halaman Anda sendiri) mencegahnya di semua browser saat ini, dan X-Frame-Options: DENY menangani browser yang lebih lama. Jika Anda sengaja menyediakan widget yang bisa disematkan, kecualikan hanya path tersebut dan hanya untuk origin yang membutuhkannya; panduan X-Frame-Options kami menjelaskan aturan server yang tepat dan error "refused to connect" yang akan Anda temui saat pengujian.

nosniff, Referrer-Policy, Permissions-Policy, dan COOP

X-Content-Type-Options: nosniff menghentikan browser dari menebak-nebak Content-Type, yang menjadi penyebab "gambar" unggahan pengguna yang berisi HTML berubah menjadi halaman yang bisa dieksekusi. Referrer-Policy: strict-origin-when-cross-origin (default di browser saat ini, tetapi tetap atur secara eksplisit) hanya mengirim origin Anda ke situs lain, sehingga token reset kata sandi dan kueri pencarian di URL tetap privat. Permissions-Policy menonaktifkan fitur browser yang tidak Anda pakai, sehingga skrip pihak ketiga yang disusupi tidak bisa membuka kamera atau membaca lokasi. Cross-Origin-Opener-Policy: same-origin memutus tautan window.opener ke halaman yang Anda buka, yang memblokir satu kelas serangan lintas jendela.

Header yang perlu dihapus juga penting: Server dan X-Powered-By mengiklankan versi software yang persis kepada scanner kerentanan, sedangkan X-XSS-Protection sudah usang dan bisa menimbulkan bug di browser lama, jadi atur ke 0 atau hapus saja. Pendeteksi CMS menunjukkan apa yang bisa dipelajari scanner tentang stack Anda hanya dari header.

Tips

Atur header sekali saja di edge (CDN, reverse proxy, atau middleware framework), bukan per halaman. Di Next.js, itu adalah file proxy atau middleware; di nginx, blok add_header dalam konteks server; di Apache, Header always set. Lalu jalankan ulang Pemeriksaan Header HTTP setelah setiap deploy, karena versi framework baru atau pengaturan CDN bisa diam-diam menghilangkan salah satunya.

Lapisan 4: Autentikasi yang Tahan Credential Stuffing

Penyerang jarang menebak kata sandi satu per satu. Mereka memutar ulang miliaran pasangan email dan kata sandi yang bocor dari situs lain (credential stuffing) dan mem-phishing sisanya. Karena itu, praktik terbaik autentikasi terdiri dari tiga bagian: simpan kata sandi sedemikian rupa sehingga kebocoran database tidak berarti kebocoran kata sandi, buat kata sandi curian tidak berguna jika berdiri sendiri, dan buat brute force terlalu lambat untuk berarti. OWASP menempatkan Authentication Failures (kegagalan autentikasi) di posisi A07 dalam OWASP Top 10:2025.

Advertisement

Hash Kata Sandi dengan Argon2id atau bcrypt

Jangan pernah menyimpan kata sandi, dan jangan pernah menyimpan hash cepat dari kata sandi. MD5, SHA-1, bahkan SHA-256 dirancang untuk cepat, sehingga tabel hash semacam itu yang bocor bisa diuji dengan miliaran tebakan per detik hanya dengan satu GPU. Gunakan fungsi hashing kata sandi yang lambat dan memory-hard dengan salt unik untuk setiap kata sandi. OWASP Password Storage Cheat Sheet merekomendasikan, secara berurutan:

  • Argon2id dengan memori minimal 19 MiB, 2 iterasi, dan tingkat paralelisme 1 (atau 46 MiB dengan 1 iterasi).

  • scrypt dengan N = 2^17, r = 8, p = 1 jika Argon2 tidak tersedia.

  • bcrypt dengan work factor 10 atau lebih (perhatikan batas input 72 byte; melakukan pre-hash pada kata sandi yang lebih panjang perlu kehati-hatian).

  • PBKDF2-HMAC-SHA256 dengan 600.000 iterasi, hanya jika kepatuhan FIPS mengharuskannya.

javascript
// Node.js with the argon2 package
import argon2 from "argon2";

const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 19456, // KiB = 19 MiB
  timeCost: 2,
  parallelism: 1,
});

// Later, on login:
const ok = await argon2.verify(hash, submittedPassword);

Catatan

Atur parameter cost agar satu hash memakan waktu sekitar 100 hingga 250 ms di server login Anda. Bagi pengguna sungguhan, jeda ini tidak terasa, tetapi membatasi penyerang hanya pada beberapa ribu tebakan per detik per core, bukan miliaran. Lakukan hash ulang saat login berhasil setiap kali Anda menaikkan parameter, sehingga hash lama memperbarui dirinya sendiri.

Aturan Kata Sandi yang Benar-Benar Membantu (NIST SP 800-63B)

Aturan komposisi yang masih diterapkan kebanyakan situs (satu huruf besar, satu simbol, ganti setiap 90 hari) menghasilkan kata sandi yang mudah ditebak seperti Summer2026! dan mendorong orang untuk memakainya berulang kali. Panduan NIST SP 800-63B terbaru menggantinya dengan aturan yang mengukur hal yang benar-benar penting:

  • Minimal 8 karakter jika MFA juga diwajibkan, dan minimal 15 karakter untuk kata sandi yang dipakai tanpa faktor lain; izinkan panjang hingga setidaknya 64 karakter.

  • Tanpa aturan komposisi dan tanpa kewajiban rotasi berkala; wajibkan penggantian hanya jika ada bukti kata sandi telah disusupi.

  • Periksa setiap kata sandi baru terhadap daftar kebocoran (range API dari Have I Been Pwned memungkinkan hal ini tanpa mengirim kata sandinya) dan tolak kata sandi yang diketahui sudah bocor.

  • Izinkan tempel (paste) dan pengelola kata sandi, terima spasi dan Unicode, serta tampilkan pengukur kekuatan berdasarkan entropi, bukan aturan.

Penguji Kekuatan Kata Sandi kami menunjukkan perbedaan ukuran-ukuran ini dengan aturan lama: alat ini memperkirakan waktu pembobolan dari entropi dan deteksi pola, serta memeriksa kata sandi terhadap data kebocoran, yang jauh lebih berguna daripada pesan merah "harus ada simbol".

MFA dan Passkey

Autentikasi multi-faktor mengubah kata sandi curian menjadi jalan buntu. Tawarkan kepada semua pengguna dan wajibkan untuk peran admin, keuangan, dan dukungan pelanggan. Urutkan pilihannya berdasarkan ketahanan terhadap phishing: passkey dan kunci keamanan FIDO2 tidak bisa di-phishing karena kredensialnya terikat pada origin Anda yang asli; aplikasi autentikator (TOTP) sudah bagus; kode SMS lebih baik daripada tidak ada, tetapi bisa disadap melalui SIM swapping. Passkey didukung di semua browser dan sistem operasi saat ini dan menghilangkan kata sandi sepenuhnya, yang sekaligus menghapus credential stuffing sebagai sebuah kategori serangan.

Lindungi jalur pemulihan akun secermat login: kode pemulihan disimpan dalam bentuk hash, reset lewat email dengan token sekali pakai yang kedaluwarsa dalam 15 menit, dan tanpa pertanyaan keamanan.

Rate Limiting, Penguncian Akun, dan Pertahanan terhadap Bot

Terapkan rate limit pada endpoint login, registrasi, reset kata sandi, dan MFA per IP dan per akun, lalu kembalikan 429 Too Many Requests dengan header Retry-After begitu batasnya tercapai (panduan kami tentang HTTP error 429 membahas bagaimana klien seharusnya merespons). Kombinasikan dengan jeda yang makin panjang atau penguncian sementara setelah kegagalan berulang pada satu akun, serta CAPTCHA atau tantangan proof-of-work untuk endpoint yang menjadi sasaran serangan terdistribusi. Catat setiap login yang gagal beserta IP sumbernya agar pola serangan credential stuffing terlihat dalam hitungan menit, bukan bulan.

nginx
# nginx: 5 login attempts per minute per client IP
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /api/login {
    limit_req zone=login burst=4 nodelay;
    limit_req_status 429;
    proxy_pass http://app;
}

Peringatan

Buat pesan error untuk "pengguna tidak dikenal" dan "kata sandi salah" sama persis, dan samakan juga waktu responsnya (lakukan hash pada kata sandi dummy jika pengguna tidak ada). Jika tidak, form login Anda sekaligus berfungsi sebagai API untuk enumerasi pengguna.

Sesi, Cookie, dan CSRF

Setelah login, cookie sesi adalah pengguna itu sendiri, jadi cookie ini layak mendapat perlindungan yang sama dengan kata sandi. Tiga atribut cookie dan satu prefiks nama melakukan sebagian besar pekerjaannya:

  • Secure berarti cookie tidak pernah dikirim melalui HTTP biasa, sehingga tidak bisa disadap di Wi-Fi publik.

  • HttpOnly membuat cookie tidak terlihat oleh JavaScript, sehingga bug XSS tidak bisa membacanya.

  • SameSite=Lax (atau Strict untuk panel admin) menjauhkan cookie dari permintaan POST lintas situs, yang menetralkan sebagian besar serangan CSRF.

  • Prefiks __Host- membuat browser menolak cookie kecuali cookie tersebut Secure, memiliki Path=/, dan tanpa atribut Domain, sehingga subdomain tidak bisa menimpanya.

http
Set-Cookie: __Host-session=9f1c7e2a...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=28800

Tips

Aksi yang mengubah state tidak boleh bisa diakses lewat GET. Tautan seperti /account/delete?id=42 bisa dipicu oleh tag <img> di halaman mana pun yang dikunjungi pengguna, sebaik apa pun flag cookie Anda.

CSRF: Lapisan Kedua di Belakang SameSite

Cross-site request forgery (CSRF) mengelabui browser yang sedang login agar mengirim permintaan yang mengubah state ke situs Anda dari halaman lain. Cookie SameSite menghentikan kasus yang umum, tetapi tetap pasang pertahanan kedua pada setiap permintaan non-GET: token anti-CSRF per sesi di field tersembunyi atau header kustom, atau pemeriksaan bahwa header Origin (atau Sec-Fetch-Site) cocok dengan origin Anda sendiri. Sebagian besar framework (Django, Rails, Laravel, server action Next.js) melakukannya secara default; kesalahannya adalah menonaktifkan perlindungan ini untuk endpoint API lalu memanggil endpoint itu dari browser.

ID Sesi, Rotasi, dan JWT

Buat ID sesi dengan keacakan minimal 128 bit, rotasi ID saat login dan setiap kali hak akses berubah untuk menggagalkan session fixation, akhiri sesi setelah tidak ada aktivitas, dan beri pengguna tombol "keluar dari semua perangkat" yang membatalkan sesi di sisi server. Untuk JWT, buat masa berlakunya singkat (hitungan menit, dengan refresh token yang bisa dicabut), jangan pernah menyimpannya di localStorage tempat skrip apa pun bisa membacanya, dan perlakukan signing key yang bocor sebagai pembobolan penuh, karena setiap token yang pernah ditandatanganinya kini bisa dipalsukan.

Injection dan XSS: Validasi Input, Encode Output

Injection (A05:2025) dan cross-site scripting adalah kesalahan yang sama di tempat berbeda: data dari pengguna diserahkan ke interpreter (SQL, shell, kueri LDAP, halaman HTML) seolah-olah data itu kode. Solusinya pun sama di mana pun: pisahkan data dari kode, dan jangan pernah menyusun perintah dengan penggabungan string.

Advertisement

Query Berparameter, Bukan Menyusun String

Untuk SQL, gunakan prepared statement atau ORM yang membuatnya; database kemudian memperlakukan input sebagai nilai yang tidak akan pernah bisa mengubah struktur query. Aturan yang sama berlaku untuk perintah shell (kirim array argumen, jangan pernah string), filter NoSQL (tolak objek operator seperti {"$gt": ""} pada input pengguna), dan path file (resolve path-nya lalu pastikan tetap berada di bawah direktori yang dimaksud).

javascript
// Vulnerable: the input becomes part of the query text
const rows = await db.query(`SELECT * FROM users WHERE email = '${email}'`);

// Safe: the driver sends the value separately from the query
const rows = await db.query("SELECT * FROM users WHERE email = $1", [email]);

// Python / psycopg: same idea
cur.execute("SELECT * FROM users WHERE email = %s", (email,))

Encoding Output Menghentikan XSS

Cross-site scripting terjadi saat teks yang dikendalikan pengguna ditulis ke halaman tanpa di-encode sesuai konteks tempatnya berada. Mesin templating modern (React dan JSX, Vue, Jinja2, Blade, ERB) melakukan encoding secara default; XSS saat ini biasanya berasal dari celah pengecualiannya (escape hatch): dangerouslySetInnerHTML, v-html, |safe, innerHTML, serta penyusunan URL atau event handler inline dari data pengguna. Lakukan encoding sesuai konteks yang tepat, dan sanitasi HTML kaya (rich HTML) dengan library khusus seperti DOMPurify, bukan dengan regex.

Tempat data beradaEncode sebagaiContoh
Body HTMLEntitas HTML< menjadi &lt;, " menjadi &quot;
Atribut HTMLEntitas di dalam atribut berkutipSelalu beri tanda kutip pada atribut; encode " dan '
JavaScriptJangan menyisipkan ke dalam teks skrip; kirim data melalui atribut data- atau blok JSON <script type="application/json"></script> di dalam string menjadi \u003c/script\u003e
Parameter URLPercent-encodingencodeURIComponent(value)
Nilai CSSHindari sepenuhnya; pilih nama class dari allowlistJangan pernah menyisipkan input pengguna ke dalam style

SSRF, Upload File, dan Deserialisasi

Server-side request forgery (SSRF): jika server Anda mengambil URL yang diberikan pengguna (webhook, proxy gambar, pratinjau tautan), penyerang bisa mengarahkannya ke layanan internal atau ke endpoint metadata cloud 169.254.169.254 dan membaca kredensial. Resolve hostname terlebih dahulu, tolak rentang IP privat dan link-local, nonaktifkan redirect, dan tempatkan fetcher di segmen jaringan yang tidak bisa menjangkau apa pun di jaringan internal.

Upload file: validasi tipe file dengan memeriksa isinya, bukan ekstensinya atau Content-Type dari klien; terapkan batas ukuran; simpan file di luar web root atau di object storage dengan nama acak yang Anda buat sendiri; dan sajikan file dari origin terpisah dengan nosniff dan Content-Disposition: attachment jika memungkinkan. Jangan pernah membiarkan file upload berada di lokasi yang akan dieksekusi oleh web server.

Deserialisasi dan mass assignment: jangan pernah melakukan deserialisasi data yang tidak tepercaya dengan format yang bisa membuat instance class sembarang (serialisasi native Java, pickle di Python, unserialize di PHP, YAML dengan tag kustom); gunakan JSON dengan skema. Ikat body request ke allowlist field yang eksplisit agar pengguna tidak bisa mengirim POST "role": "admin" ke model yang kebetulan memiliki kolom tersebut.

Peringatan

Validasi berfungsi untuk memastikan bentuk data (apakah ini email, bilangan bulat positif, salah satu dari lima nilai ini?), bukan untuk keamanan. Blocklist yang menghapus <script> atau karakter tanda kutip selalu bisa ditembus. Terima hanya yang Anda harapkan, lalu encode saat output dan gunakan parameter saat menyimpan.

Broken Access Control: Risiko Nomor Satu

Broken Access Control (kontrol akses yang rusak) menduduki posisi teratas OWASP Top 10 sejak 2021 dan tetap bertahan sebagai A01:2025. Ini bukan satu bug, melainkan kebiasaan: memeriksa siapa seseorang (autentikasi) tetapi lupa memeriksa apa yang boleh ia akses (otorisasi) di setiap permintaan. Bentuk klasiknya adalah insecure direct object reference (IDOR): GET /api/invoices/1042 berfungsi untuk pemilik invoice tersebut, dan juga untuk siapa pun yang mengganti angkanya.

  • Tolak secara default. Setiap route memerlukan aturan eksplisit yang memberikan akses; aturan yang tidak ada berarti 403, bukan 200.

  • Terapkan di server, per objek. Menyembunyikan tombol di UI bukanlah kontrol akses. Setiap operasi baca dan tulis harus memastikan pengguna saat ini memiliki atau diizinkan mengakses record spesifik tersebut, termasuk di endpoint massal, fitur ekspor, dan background job.

  • Gunakan ID yang tidak bisa ditebak jika membantu (UUID), tetapi jangan pernah mengandalkannya: menyamarkan bukanlah otorisasi.

  • Perketat CORS. Access-Control-Allow-Origin: * dengan kredensial, atau memantulkan Origin apa pun yang dikirim request, sama saja dengan menyerahkan API Anda ke website mana pun yang dikunjungi pengguna.

  • Nonaktifkan directory listing, blokir .git, .env, file backup, dan file konfigurasi di tingkat web server, serta jauhkan panel admin dari internet publik atau lindungi dengan MFA dan allowlist IP.

  • Terapkan rate limit dan catat kegagalan otorisasi. Lonjakan 403 dari satu sesi adalah tanda serangan enumerasi yang sedang berlangsung.

javascript
// Express: ownership check on every object access
app.get("/api/invoices/:id", requireAuth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (!invoice || invoice.ownerId !== req.user.id) {
    return res.status(404).end(); // 404, not 403: don't confirm the record exists
  }
  res.json(invoice);
});

Catatan

Uji kontrol akses seperti yang dilakukan penyerang: login sebagai pengguna dengan hak akses rendah, rekam setiap request, lalu putar ulang masing-masing dengan ID milik pengguna lain dan tanpa header Authorization. Scanner otomatis bisa menemukan injection, tetapi hampir tidak pernah menemukan bug otorisasi, itulah sebabnya bug semacam ini bisa bertahan bertahun-tahun.

Lapisan 5: Dependensi dan Software Supply Chain

Aplikasi web pada umumnya berisi mungkin hanya 5% kode yang Anda tulis dan 95% kode yang Anda unduh. Itulah sebabnya Software Supply Chain Failures (kegagalan rantai pasok software) langsung masuk di posisi A03 dalam OWASP Top 10 2025, dan mengapa eksploitasi kerentanan menyalip kredensial curian dalam DBIR 2026. Pada September 2025, satu maintainer yang terkena phishing menyisipkan malware pencuri kripto ke chalk, debug, dan 16 paket npm lain yang secara total diunduh lebih dari dua miliar kali per minggu; setiap proyek yang menginstal versi yang tidak di-pin selama rentang waktu itu otomatis ikut menariknya.

  • Commit lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, poetry.lock, go.sum) dan instal dengan npm ci di CI agar build bisa direproduksi dan rilis upstream baru tidak bisa menyelinap masuk tanpa ditinjau.

  • Scan terus-menerus: npm audit, pip-audit, bundler-audit, GitHub Dependabot atau Renovate untuk pembaruan, serta scanner container seperti Trivy atau Grype untuk lapisan OS.

  • Tunda upgrade non-keamanan beberapa hari (minimumReleaseAge di Renovate) agar rilis yang diracuni biasanya sudah ditarik sebelum Anda mengadopsinya, tetapi terapkan patch keamanan segera.

  • Pin action dan skrip pihak ketiga ke SHA commit di CI, dan gunakan Subresource Integrity (integrity="sha384-...") pada skrip apa pun yang Anda muat dari CDN publik.

  • Beri CI hak akses seminimal mungkin: token read-only jika memungkinkan, kredensial OIDC berumur pendek alih-alih secret berumur panjang, dan hak publikasi yang dibatasi hanya untuk job rilis.

  • Buat SBOM (CycloneDX atau SPDX) saat build agar Anda bisa menjawab "apakah kita terdampak?" dalam hitungan menit saat CVE sekelas Log4Shell berikutnya muncul.

bash
# Reproducible install + audit in CI
npm ci --ignore-scripts
npm audit --audit-level=high

# Pin a GitHub Action to a commit, not a floating tag
# uses: actions/checkout@v4                 <- can change underneath you
# uses: actions/checkout@<full-commit-sha>  # v4.2.2

# Subresource Integrity for a CDN script (hash from: openssl dgst -sha384 -binary lib.min.js | openssl base64 -A)
<script src="https://cdn.example.com/lib.min.js"
        integrity="sha384-<base64-hash>"
        crossorigin="anonymous"></script>

Tips

npm ci --ignore-scripts memblokir skrip saat instalasi yang dipakai sebagian besar malware npm untuk berjalan; setelah itu aktifkan kembali skrip hanya untuk segelintir paket yang memang membutuhkan langkah build.

Jika Anda menjalankan WordPress atau CMS lain, aturan yang sama berlaku untuk plugin dan tema, yang menjadi titik awal sebagian besar kasus pembobolan CMS. Selalu perbarui core dan setiap plugin, hapus yang tidak Anda pakai, dan periksa apa yang bisa diketahui scanner tentang versi Anda dengan Pendeteksi CMS.

Lapisan 6: Hardening Server (Port, Patch, Secret, Backup)

Lapisan aplikasi tidak ada artinya jika server di bawahnya menerima login SSH dengan kata sandi, menjalankan database di port publik, atau belum pernah di-patch sejak pertama kali dibangun. Praktik terbaik server memang membosankan, dan justru di situlah ransomware masuk.

Tutup Setiap Port yang Tidak Anda Layani

Web server publik membutuhkan port 80 dan 443 terbuka, serta SSH dari rentang IP Anda sendiri. Database (3306, 5432, 27017), Redis (6379), Elasticsearch (9200), panel admin, dan endpoint metrik sebaiknya hanya bind ke localhost atau jaringan privat. Periksa dari luar dengan Pemeriksa Port setelah setiap perubahan, karena itulah sudut pandang yang didapat penyerang, dan security group di cloud mudah salah dibaca.

bash
# Ubuntu: default-deny firewall, allow only web + SSH from your office range
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw enable

# SSH: keys only, no root password login
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo systemctl reload ssh

Patch Secara Terjadwal, Jauhkan Secret dari Kode

Aktifkan pembaruan keamanan otomatis (unattended) untuk sistem operasi, berlangganan milis keamanan untuk runtime dan framework Anda, dan perlakukan CVE kritis pada apa pun yang terhubung ke internet sebagai pekerjaan yang harus selesai hari itu juga. Jalankan layanan sebagai pengguna tanpa hak istimewa, di dalam container atau dengan sandboxing systemd, sehingga proses yang disusupi tidak bisa membaca seluruh mesin.

Secret (kata sandi database, API key, signing key) tidak boleh berada di repository, di layer image Docker, atau di JavaScript sisi klien. Muat secret dari environment variable yang disuntikkan saat deploy atau dari secrets manager, rotasi saat seseorang yang memiliki akses keluar, dan pindai riwayat repository dengan tool seperti gitleaks, karena kunci yang pernah di-commit sekali akan tetap dianggap bocor selamanya, bahkan setelah commit-nya dihapus.

Peringatan

Apa pun yang berawalan NEXT_PUBLIC_, VITE_, atau REACT_APP_ dibundel ke browser dan secara definisi bersifat publik. Letakkan API key pihak ketiga di balik route server Anda sendiri. Panduan kami tentang menguji endpoint API publik menunjukkan cara memastikan apa yang sebenarnya diekspos oleh frontend Anda.

Backup yang Tahan Ransomware, dan CDN di Depan Server

Ikuti aturan 3-2-1: tiga salinan, di dua media berbeda, satu di luar lokasi (off-site), dan jadikan setidaknya satu salinan immutable atau offline agar ransomware yang mencapai server tidak bisa ikut mengenkripsi backup. Enkripsi backup, sertakan database dan direktori upload, dan yang terpenting, uji proses restore secara terjadwal. Backup yang belum pernah dipulihkan hanyalah harapan, bukan rencana. Waktu pemulihan adalah faktor yang menentukan apakah sebuah insiden hanya menjadi gangguan layanan atau peristiwa yang mengakhiri perusahaan.

Tempatkan CDN atau WAF (Cloudflare, Fastly, AWS CloudFront dengan WAF, atau layanan setara dari host Anda) di depan origin. CDN atau WAF menyerap DDoS volumetrik, menerapkan aturan terkelola untuk payload injection yang umum dan bot jahat, menyembunyikan IP origin Anda, dan memberi Anda tempat untuk menerapkan rate limit dan aturan geografis tanpa menyentuh aplikasi. Lalu batasi firewall origin agar hanya rentang IP milik CDN yang bisa mengakses port 443 secara langsung; jika tidak, penyerang cukup memutarinya. Cek Hosting Website menunjukkan apakah origin asli sebuah situs terekspos di balik CDN-nya.

Autentikasi Email: SPF, DKIM, dan DMARC

Keamanan web juga mencakup email yang membawa reset kata sandi, invoice, dan balasan dukungan pelanggan Anda. Tanpa SPF, DKIM, dan DMARC, siapa pun bisa mengirim email sebagai billing@yourdomain.com, dan sejak Februari 2024 Google dan Yahoo mewajibkan ketiganya bagi pengirim massal. Set lengkapnya terdiri dari tiga record TXT DNS:

dns
yourdomain.com.                    TXT  "v=spf1 include:_spf.google.com -all"
google._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
_dmarc.yourdomain.com.             TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"

Catatan

DMARC p=reject juga merupakan kontrol perlindungan merek: hanya inilah yang bisa mencegah kampanye phishing mencantumkan domain Anda yang persis di baris From. Laporan agregat (rua=) menunjukkan siapa yang sedang mencobanya.

Mulai DMARC di p=none untuk mengumpulkan laporan, lalu naik ke p=quarantine dan kemudian p=reject setelah setiap pengirim yang sah (platform marketing, helpdesk, CRM) lolos alignment. Tambahkan record MTA-STS dan TLS-RPT untuk memaksa pengiriman terenkripsi ke server email Anda, dan publikasikan null MX (MX 0 .) pada domain yang tidak pernah mengirim email agar domain itu sama sekali tidak bisa dipalsukan. Verifikasi setiap record dengan Pemeriksa Rekaman SPF, Pemeriksa DKIM, dan Pemeriksa DMARC, serta periksa IP pengirim Anda terhadap daftar blokir dengan Pemeriksaan Daftar Hitam IP jika tingkat keterkiriman (deliverability) menurun.

Log, Pantau, dan Bersiap Menghadapi Pembobolan

Dua dari sepuluh kategori OWASP 2025 membahas apa yang terjadi setelah sebuah kesalahan: Security Logging and Alerting Failures (A09) dan kategori baru Mishandling of Exceptional Conditions (A10). Pembobolan pada umumnya masih tidak terdeteksi selama berbulan-bulan karena buktinya tidak pernah dicatat, atau sudah dicatat tetapi tidak ada yang melihatnya.

  • Catat event keamanan beserta konteksnya: setiap login yang berhasil maupun gagal, perubahan MFA, reset kata sandi, perubahan izin, penolakan kontrol akses, kegagalan validasi input, dan aksi admin, masing-masing dengan timestamp, ID pengguna, IP sumber, dan user agent.

  • Jangan pernah mencatat secret: kata sandi, token sesi, nomor kartu lengkap, API key. Samarkan di lapisan logging, bukan di setiap titik pemanggilan.

  • Kirim log keluar dari server ke penyimpanan terpusat (CloudWatch, Loki, Elastic, SIEM) dengan retensi minimal 90 hari, agar penyerang yang punya akses root tidak bisa menghapus jejaknya.

  • Pasang peringatan berdasarkan pola, bukan event tunggal: 50 login gagal dalam semenit, lonjakan 403 dari satu sesi, admin baru yang dibuat di luar jam kerja, sertifikat yang diterbitkan untuk domain Anda padahal tidak pernah Anda minta.

  • Fail closed: ketika pemeriksaan di hilir (layanan autentikasi, rate limiter, WAF) mengalami error, tolak request tersebut. A10 ada karena begitu banyak sistem justru memberikan akses ketika pemeriksaan yang seharusnya memblokir malah melempar exception.

  • Pantau dari luar: uptime, kedaluwarsa sertifikat, perubahan DNS, pencantuman di daftar blokir, dan regresi header. Pemeriksa Kesehatan Domain menggabungkan pemeriksaan DNS, SSL, autentikasi email, dan header ke dalam satu skor yang bisa Anda jalankan ulang setelah setiap deploy.

Tulis Rencana Respons Insiden Sebelum Anda Membutuhkannya

Tentukan sejak awal siapa yang siaga (on-call), cara merotasi setiap kredensial, cara mengubah situs menjadi read-only, di mana backup yang bersih disimpan, dan regulator atau pelanggan mana yang harus diberi tahu serta dalam berapa jam (72 jam menurut GDPR). Jalankan latihan tabletop setahun sekali. Tim dengan rencana yang sudah dilatih bisa pulih dalam hitungan hari; tim tanpa rencana berimprovisasi selama berminggu-minggu.

Tips

Tambahkan file security.txt di /.well-known/security.txt (RFC 9116) yang berisi alamat kontak dan kunci PGP. Peneliti yang menemukan bug di situs Anda akan memakainya; alternatifnya, mereka mempublikasikan bug itu secara terbuka.

Uji: Scanner, Pentest, dan Pemeriksaan Berkelanjutan

Setiap kontrol di atas bisa diverifikasi, dan verifikasinya sebaiknya diotomatiskan sebisa mungkin agar tidak tergerus seiring waktu. Berikut tangga yang masuk akal, dari yang gratis dan instan hingga yang berkala dan berbayar:

PemeriksaanToolSeberapa sering
Konfigurasi TLS, rantai sertifikat, masa berlakuPemeriksaan Sertifikat SSL, SSL Labs, testssl.shSetelah setiap perubahan sertifikat atau server; masa berlaku setiap hari
Security header dan CSPPemeriksaan Header HTTP, MDN HTTP ObservatorySetelah setiap deploy (masukkan ke CI)
Port terbukaPemeriksa Port, nmapSetelah setiap perubahan firewall atau cloud
DNS, DNSSEC, autentikasi emailPemeriksa Kesehatan Domain, Pemeriksa DMARCBulanan, dan setelah setiap perubahan DNS
Subdomain usangPencari SubdomainSetiap kuartal dan setiap kali layanan dinonaktifkan
Dependensi yang diketahui rentannpm audit, Dependabot, TrivySetiap build
Celah di level kode (SAST)Semgrep, CodeQLSetiap pull request
Kerentanan web saat runtime (DAST)OWASP ZAP, NucleiMingguan terhadap staging
Otorisasi dan logika bisnisPenetration test manual atau program bug bountyTahunan, dan setelah fitur besar dirilis

Scanner andal dalam menemukan injection, masalah header, dan komponen usang, tetapi lemah dalam otorisasi dan logika bisnis, jadi anggarkan setidaknya satu pengujian oleh manusia per tahun untuk apa pun yang menangani uang atau data pribadi. Perbaiki berdasarkan tingkat keterpaparan: apa pun yang bisa dieksploitasi pengguna tanpa autentikasi dari internet harus didahulukan.

Checklist Keamanan Website

Salin ini ke README proyek atau issue tracker Anda. Setiap baris adalah salah satu praktik di atas, dirumuskan agar bisa ditandai selesai atau belum; kolom terakhir adalah buktinya.

LapisanPraktikSelesai jika
DomainRegistrar lock dan MFA di akun registrar; perpanjangan otomatis aktifWHOIS menampilkan clientTransferProhibited; masa berlaku masih lebih dari 12 bulan
DNSZona ditandatangani DNSSEC; record CAA hanya mencantumkan CA Andadig +dnssec mengembalikan RRSIG; record DS ada di zona induk
DNSTidak ada record CNAME atau A yang menggantung (dangling)Setiap hostname dari Pencari Subdomain mengarah ke sesuatu yang Anda kendalikan
TLSHanya TLS 1.2+, TLS 1.3 diutamakan, rantai sertifikat lengkap disajikanPemeriksaan Sertifikat SSL: rantai lengkap, TLS 1.0/1.1 ditolak
TLSHSTS dengan max-age satu tahun, includeSubDomains, sudah di-preloadTercantum di hstspreload.org
TLSPerpanjangan diotomatiskan lewat ACME; masa berlaku dipantaucertbot renew --dry-run berhasil; peringatan dipasang pada 14 hari
HeaderCSP (berbasis nonce), frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyNilai A di Pemeriksaan Header HTTP
AutentikasiHashing Argon2id atau bcrypt; aturan kata sandi NIST; pemeriksaan daftar kebocoranSatu hash memakan waktu 100 hingga 250 ms; tanpa aturan komposisi
AutentikasiMFA ditawarkan ke semua pengguna, wajib untuk admin; passkey didukungLogin admin tidak mungkin tanpa faktor kedua
AutentikasiEndpoint login, reset, dan MFA dibatasi rate limit per IP dan per akunPercobaan keenam dalam satu menit mengembalikan 429
SesiCookie __Host- dengan Secure, HttpOnly, SameSite; ID dirotasi saat loginAtribut cookie terlihat di DevTools; sesi lama tidak valid setelah login
InputQuery berparameter di semua tempat; output di-encode sesuai konteks; upload divalidasi berdasarkan isinyaTidak ada query hasil penyusunan string dalam pencarian kode; payload XSS tampil sebagai teks
Kontrol aksesRouting tolak-secara-default; pemeriksaan kepemilikan per objek; CORS ketatMemutar ulang ID pengguna lain mengembalikan 404 atau 403
DependensiLockfile di-commit; npm ci; audit di CI; action di-pin ke SHA; SRI pada skrip CDNBuild gagal jika ada CVE dengan tingkat keparahan tinggi
ServerHanya 80 dan 443 yang publik; SSH hanya dengan kunci; pembaruan keamanan otomatis; secret di env atau vaultPemeriksa Port menunjukkan port 22, 3306, dan 6379 tertutup dari internet
Backup3-2-1 dengan satu salinan immutable; restore sudah diujiUji restore terakhir yang berhasil bertanggal dalam 90 hari terakhir
EmailSPF -all, DKIM, DMARC p=reject, MTA-STSLolos Pemeriksa DMARC; laporan agregat berdatangan
MonitoringEvent autentikasi dan otorisasi dicatat secara terpusat; peringatan berbasis pola; pemantauan uptime, sertifikat, dan DNS dari luarPeringatan uji sudah dipicu dan diterima
ResponsRencana insiden tertulis; security.txt dipublikasikan; latihan tabletop sudah dijalankanRencana ditinjau dalam 12 bulan terakhir

Pemetaan ke OWASP Top 10:2025

OWASP Top 10 adalah daftar risiko aplikasi web yang paling banyak dikutip, dan edisi 2025-nya mengubah urutan serta memperkenalkan dua kategori baru. Jika klien, auditor, atau framework kepatuhan menanyakan bagaimana Anda menanganinya, inilah pemetaannya ke praktik-praktik dalam panduan ini:

OWASP Top 10:2025Praktik dalam panduan ini
A01 Broken Access ControlTolak secara default, pemeriksaan per objek, CORS ketat, penguncian panel admin
A02 Security MisconfigurationSecurity header, HSTS, port tertutup, header versi dihapus, directory listing dinonaktifkan
A03 Software Supply Chain Failures (baru)Lockfile, audit, action yang di-pin, SRI, SBOM, CI dengan hak akses minimum
A04 Cryptographic FailuresTLS 1.2+ dan 1.3, HSTS, Argon2id, pengelolaan secret, backup terenkripsi
A05 InjectionQuery berparameter, encoding output, CSP, validasi upload
A06 Insecure DesignThreat model per lapisan, default fail-closed, rate limiting sejak tahap desain
A07 Authentication FailuresAturan kata sandi NIST, pemeriksaan kebocoran, MFA dan passkey, rotasi sesi
A08 Software or Data Integrity FailuresSRI, dependensi yang ditandatangani dan di-pin, deserialisasi yang aman
A09 Security Logging and Alerting FailuresLogging terpusat, peringatan berbasis pola, pemantauan eksternal
A10 Mishandling of Exceptional Conditions (baru)Fail closed, respons error yang seragam, tanpa stack trace ke pengguna

Catatan

ASVS (Application Security Verification Standard) dari OWASP mengubah materi yang sama menjadi checklist bernomor untuk audit. Level 1 adalah target yang realistis untuk situs publik apa pun; Level 2 untuk apa pun yang menangani data pribadi atau keuangan.

Cek security header situs Anda dalam hitungan detik

Pemeriksaan Header HTTP gratis dari DNS Robot mengambil URL apa pun dan menilai security header-nya dari A sampai F: HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, dan Permissions-Policy, lengkap dengan nilai persis yang ditemukan dan apa yang belum ada. Tanpa perlu mendaftar.

Coba Pemeriksaan Header HTTP

Advertisement

FAQ Keamanan Website

Wajibkan HTTPS dengan TLS modern dan HSTS, kirim security header yang ketat (terutama Content Security Policy), hash kata sandi dengan Argon2id yang dilengkapi MFA dan rate limiting, gunakan query berparameter dan encoding output, terapkan kontrol akses di server untuk setiap objek, jaga dependensi tetap ter-patch dan di-pin, tutup port yang tidak dipakai, dan catat event keamanan secara terpusat. Kunci domain dan DNS terlebih dahulu, karena semua hal lain bergantung pada kendali Anda atas nama domain tersebut.

Alat Terkait

HTTP Headers CheckSSL Certificate CheckPort CheckerDomain Health CheckerDMARC CheckerSubdomain FinderPassword Strength Tester

Artikel Terkait

Apa Itu Rantai Sertifikat SSL? Cara KerjanyaX-Frame-Options Explained: Fix “Refused to Connect” in an iframeHTTP Error 429 Too Many Requests: Penyebab & Cara MengatasinyaWHOIS Domain: Cara Cek Pemilik Domain dan Membaca Record-nya

Daftar Isi

  • Apa Itu Praktik Terbaik Keamanan Website?
  • Tumpukan Keamanan Web: Enam Lapisan yang Harus Dilindungi
  • Lapisan 1: Kunci Domain dan DNS
  • Lapisan 2: HTTPS dan TLS yang Dikonfigurasi dengan Benar
  • Lapisan 3: Header Keamanan HTTP (Security Headers)
  • Lapisan 4: Autentikasi yang Tahan Credential Stuffing
  • Sesi, Cookie, dan CSRF
  • Injection dan XSS: Validasi Input, Encode Output
  • Broken Access Control: Risiko Nomor Satu
  • Lapisan 5: Dependensi dan Software Supply Chain
  • Lapisan 6: Hardening Server (Port, Patch, Secret, Backup)
  • Autentikasi Email: SPF, DKIM, dan DMARC
  • Log, Pantau, dan Bersiap Menghadapi Pembobolan
  • Uji: Scanner, Pentest, dan Pemeriksaan Berkelanjutan
  • Checklist Keamanan Website
  • Pemetaan ke OWASP Top 10:2025
  • Pertanyaan yang Sering Diajukan