Link Reset Password Memerlukan Origin Publik yang Tepercaya
Email reset password sering memuat salah satu URL paling sensitif yang dibuat aplikasi. Kepemilikan token reset yang valid dapat cukup untuk menetapkan kredensial baru bagi akun terkait, sehingga tujuan yang ditanamkan pada URL tersebut merupakan bagian dari batas keamanan.
Kesalahan implementasi yang umum adalah membentuk URL reset absolut dari informasi host pada HTTP request yang masuk. Header seperti Host digunakan untuk routing request, sedangkan deployment di belakang proxy juga dapat mengekspos metadata host atau scheme yang diteruskan. Kecuali aplikasi telah menetapkan secara eksplisit intermediary mana yang dipercaya dan nilai mana yang valid, metadata request tersebut bukan sumber otoritas yang aman untuk link keluar yang sensitif terhadap keamanan.
Desain yang lebih aman lebih sederhana: tetapkan origin publik aplikasi dari state deployment yang tepercaya, lalu tambahkan path reset dan token ke origin tersebut.
Metadata routing request bukan identitas aplikasi
HTTP request memerlukan informasi yang cukup agar infrastruktur dapat melakukan routing. Hal itu tidak menjadikan setiap nilai routing sebagai pernyataan tepercaya mengenai identitas eksternal kanonis aplikasi.
Pertimbangkan handler reset yang secara efektif menjalankan operasi berikut:
origin = "https://" + request.host
reset_url = origin + "/reset?token=" + token
send_email(account.email, reset_url)Jika client yang tidak tepercaya dapat memengaruhi request.host, aplikasi dapat membuat token valid lalu menaruhnya dalam URL dengan authority yang menunjuk ke tempat lain. Kualitas kriptografis token tidak memperbaiki kesalahan tujuan tersebut. Token dengan entropy tinggi yang dikirim ke origin yang salah tetap terekspos kepada origin itu ketika penerima membuka link.
Persoalan desain yang sama berlaku ketika framework merekonstruksi URL eksternal dari X-Forwarded-Host, Forwarded, atau metadata proxy serupa. Header tersebut dapat sah di dalam rantai proxy yang dikendalikan, tetapi memerlukan model kepercayaan eksplisit. Menerimanya langsung dari client arbitrer mengubah metadata deployment menjadi input penyerang.
Pembuatan URL reset sebaiknya dimulai dari konfigurasi
Sebuah deployment biasanya memiliki sejumlah kecil origin publik yang valid untuk pemulihan akun. Simpan origin tersebut dalam konfigurasi yang dikendalikan operator, bukan menurunkannya dari setiap request reset.
Untuk aplikasi dengan satu origin, aturannya dapat dibuat langsung:
PUBLIC_ORIGIN = "https://accounts.example.com"
token = create_reset_token(account)
reset_url = PUBLIC_ORIGIN + "/reset?token=" + url_encode(token)
send_email(account.email, reset_url)Request tetap dapat membawa metadata host untuk routing, logging, atau pemilihan virtual host. Metadata tersebut hanya tidak menentukan ke mana token pemulihan kredensial dikirim.
Sistem multi-tenant memerlukan pemetaan yang lebih terarah. Jika tenant memang memakai domain berbeda, tentukan origin publik dari konfigurasi tenant yang tepercaya setelah identitas tenant ditetapkan. Jangan izinkan caller memasok origin arbitrer hanya karena aplikasi mendukung custom domain.
Validasi host dan pembuatan URL menangani masalah yang berkaitan tetapi berbeda
Menolak host yang tidak diharapkan pada edge atau layer aplikasi tetap berguna. Kontrol ini mengurangi perilaku virtual host yang ambigu dan dapat memblokir request yang seharusnya tidak pernah mencapai aplikasi. Namun, kontrol tersebut tidak sebaiknya menjadi satu-satunya perlindungan untuk pembuatan URL reset.
Origin publik dari konfigurasi memberi URL builder sumber kebenaran yang independen. Jika layer routing kemudian berubah atau header proxy baru terlihat oleh aplikasi, link reset tidak otomatis mewarisi nilai tersebut.
Sebaliknya, origin publik yang tepercaya tidak menghapus kebutuhan validasi host. Nilai host yang tidak diharapkan dapat memengaruhi redirect, cache key, absolute link, routing virtual host, dan perilaku lain. Kedua kontrol melindungi titik yang berbeda pada jalur request dan response.
Kepercayaan terhadap proxy harus eksplisit
Reverse proxy lazim menghentikan TLS lalu meneruskan request ke aplikasi melalui koneksi internal. Framework dapat memakai forwarded header untuk merekonstruksi scheme dan host eksternal. Perilaku ini dapat benar jika aplikasi hanya menerima header tersebut dari proxy tepercaya dan proxy mengganti nilai yang dikirim client dengan nilai otoritatif.
Konfigurasi berbahaya muncul ketika batas kepercayaan bercampur: aplikasi menganggap metadata forwarded sebagai otoritatif sementara client eksternal dapat memasok atau mempertahankan metadata yang sama.
Deployment yang kuat menetapkan hop proxy yang dipercaya, menghapus atau menimpa forwarding header terkait pada boundary, serta mengatur framework aplikasi agar menghormati metadata proxy hanya dalam kondisi tersebut. Pembuatan link sensitif terhadap keamanan tetap sebaiknya memakai konfigurasi aplikasi eksplisit ketika origin publik yang diharapkan sudah diketahui.
Token reset tetap memerlukan kontrol lifecycle sendiri
Memperbaiki origin melindungi tujuan pengiriman, tetapi tidak otomatis membuat token reset aman. Token perlu dibuat dengan tingkat ketidak-terdugaan yang memadai, diikat ke akun atau transaksi pemulihan yang dituju, memiliki masa berlaku terbatas, dan tidak dapat digunakan lagi setelah konsumsi berhasil.
Aplikasi juga sebaiknya tidak mengekspos token melalui perilaku halaman yang tidak terkait. Halaman reset yang memuat resource pihak ketiga dapat membuka jalur pengungkapan tambahan, bergantung pada perilaku referrer browser dan desain halaman. Menjaga halaman pemulihan tetap minimal serta menetapkan Referrer-Policy yang sesuai mengurangi penyebaran data URL sensitif yang tidak diperlukan.
Setelah token diterima, server tetap harus menegakkan alur pemulihan: memverifikasi token, menerapkan kebijakan password yang dituju, membatalkan token setelah dipakai, dan menangani session yang masih aktif sesuai kebijakan keamanan akun aplikasi.
Pengujian perlu menyentuh batas kepercayaan
Pengujian yang berguna mengubah metadata request terkait host saat proses reset dimulai, lalu memeriksa email yang dihasilkan. Tujuan link harus tetap berada pada origin aplikasi yang telah dikonfigurasi.
Uji nilai yang benar-benar diekspos oleh stack deployment, termasuk Host serta field forwarded host atau scheme yang melewati proxy. Uji pula nilai host yang malformed atau tidak diharapkan untuk memastikan validasi routing berperilaku sesuai desain.
Untuk deployment multi-tenant, pastikan satu tenant tidak dapat memilih origin pemulihan milik tenant lain dan custom domain yang belum terdaftar tidak dapat masuk ke pemetaan. Origin yang diharapkan harus berasal dari state tenant yang tepercaya, bukan parameter URL atau header yang tidak diperiksa.
Pengujian menjadi lebih kuat ketika memeriksa artefak akhir yang dikirim kepada pengguna, bukan hanya object request perantara. Properti keamanannya konkret: token pemulihan yang valid tidak boleh ditanamkan pada link menuju origin yang dipilih requester yang tidak tepercaya.
Pisahkan otoritas dari input
Alur reset password melintasi beberapa batas sekaligus: request tanpa autentikasi memulai proses, server membuat token berprivilege, email mengangkutnya, lalu browser mengembalikannya ke aplikasi. Origin pada URL reset menghubungkan tahap-tahap tersebut.
Memperlakukan origin itu sebagai otoritas deployment, bukan input request, menjaga rantai tetap terikat ke tujuan yang dipilih operator. Validasi host, kepercayaan proxy yang disiplin, kontrol lifecycle token, dan halaman pemulihan yang minimal kemudian memperkuat batas yang sama tanpa bergantung pada satu header untuk mendefinisikan identitas aplikasi.