Topik wawancara representatif

Wawancara Backend: Bagaimana Anda merancang alur ubah email yang aman?

BackendSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Pengguna yang sudah masuk (signed-in) ingin mengubah akun dari old@example.com ke new@example.com. Rancang alur backend yang tahan terhadap pencurian sesi, salah ketik alamat, permintaan duplikat, dan race condition.

Petunjuk dan konteks

Pengguna yang sudah masuk mengirimkan alamat email baru. Layanan harus membuktikan kepemilikan atas alamat baru tersebut sambil mengurangi risiko pengambilalihan akun (account takeover) akibat sesi yang dicuri, enumerasi email, klik berulang, dan permintaan konkuren. Jelaskan model data, siklus hidup token, notifikasi, kebijakan sesi, batas laju, peristiwa audit, dan jalur pemulihan.

Asumsikan bahwa mengubah email memengaruhi proses masuk, pemulihan kata sandi, dan pemberitahuan keamanan, sehingga ini merupakan tindakan akun berisiko tinggi. Sesi saat ini mungkin telah dicuri, salah satu alamat mungkin tidak dapat diakses untuk sementara, dan hanya satu permintaan perubahan yang boleh aktif untuk satu akun.

Hal yang diuji oleh pewawancara

Pewawancara ingin mendengar perbedaan antara sesi aktif dan identitas yang baru saja dibuktikan ulang. Jawaban yang kuat mewajibkan autentikasi ulang atau metode autentikasi multifaktor yang sudah ada untuk akun berisiko tinggi. Mereka memisahkan alamat yang diajukan hingga pembuktian berhasil.

Mereka juga mencari token acak sekali pakai, masa berlaku singkat, digest token di sisi server, pencegahan replay, notifikasi ke alamat lama, respons kesalahan yang seragam, dan peristiwa audit. Jawaban yang sangat baik mencakup pencabutan sesi, pemulihan, dan invarian untuk pembaruan konkuren.

Jawaban 30 detik

"Saya akan mewajibkan autentikasi ulang baru-baru ini, dan metode MFA yang ada untuk akun berisiko lebih tinggi. Saya akan menyimpan alamat yang diajukan dalam rekaman tertunda (pending) terpisah alih-alih mengganti alamat saat ini. Token acak sekali pakai yang aman secara kriptografi akan dikirimkan melalui email ke alamat baru; basis data hanya menyimpan digest, tujuan, masa kedaluwarsa, dan status penggunaannya. Transaksi konfirmasi mengunci akun, memeriksa digest, masa kedaluwarsa, dan versi, lalu secara atomik mengubah alamat dan menandai permintaan telah digunakan. Alamat lama menerima pemberitahuan keamanan dan opsi pembatalan. Sesi dicabut atau ditingkatkan (stepped up) sesuai tingkat risiko. Respons aman dari enumerasi, permintaan dibatasi lajunya, dan peristiwa audit tidak pernah memuat token."

Pembahasan mendalam langkah demi langkah

Langkah 1: Modelkan akun dan permintaan yang tertunda

Pertahankan current_email pada akun dan simpan rekaman pending_email_change terpisah yang berisi ID akun, alamat yang diajukan yang telah dinormalisasi, digest token, tujuan, masa kedaluwarsa, status, versi, waktu pembuatan, dan konteks risiko sesi yang menginisiasi. Hingga pembuktian berhasil, nilai yang diajukan tidak boleh memengaruhi proses masuk atau pemulihan.

Langkah 2: Autentikasi ulang dan tetapkan batasan risiko

Sesi masuk yang aktif hanya membuktikan bahwa sesi tersebut diterima. Wajibkan pemeriksaan kata sandi terbaru atau faktor MFA yang ada, dan pertimbangkan sinyal perangkat, IP, serta anomali. Mengetahui alamat baru tidak membuktikan identitas saat ini. Hasil step-up harus berumur pendek dan bertujuan tunggal, bukan kredensial universal yang bertahan lama.

Langkah 3: Buat dan kirimkan token sekali pakai

Gunakan generator acak yang aman secara kriptografi, TTL pendek, dan satu tujuan. Simpan hanya digest satu arah di basis data; tautan email membawa token mentah. Pesan tidak boleh mengungkapkan apakah sebuah akun ada atau tidak. Pengiriman ulang dibatasi lajunya dan membatalkan token yang lebih lama. Token yang sudah digunakan, kedaluwarsa, atau digantikan tidak dapat digunakan kembali.

Langkah 4: Verifikasi dan lakukan commit secara atomik

Saat konfirmasi, lakukan pemeriksaan format dan batas laju, lalu kunci baris akun dan status tertunda dalam satu transaksi. Bandingkan digest dalam waktu konstan (constant time) dan periksa status, TTL, tujuan, serta versi. Terapkan keunikan alamat baru dalam transaksi yang sama, perbarui email saat ini secara atomik, tandai permintaan telah digunakan, dan tambahkan peristiwa audit. Klik duplikat mengembalikan hasil yang idempoten atau telah diproses dengan aman tanpa mengulangi efek samping.

Langkah 5: Tangani alamat lama, sesi, dan notifikasi

Kirimkan pemberitahuan keamanan ke alamat lama dan izinkan pembatalan selama permintaan masih berstatus tertunda. Jika berhasil, cabut token penyegar (refresh token) berumur panjang atau wajibkan sesi lain untuk melakukan autentikasi ulang; akun berisiko tinggi mungkin memerlukan pencabutan global segera. Alamat baru tidak boleh langsung menjadi satu-satunya bukti pemulihan instan.

Langkah 6: Kendalikan enumerasi, penyalahgunaan, dan race condition

Gunakan durasi waktu dan pesan yang seragam untuk titik akhir permintaan dan konfirmasi, sehingga penyerang tidak dapat mengetahui apakah suatu alamat telah terdaftar. Terapkan pembatasan laju berdasarkan akun, alamat tujuan, perangkat, dan jaringan. Batasan keunikan ditambah penguncian baris atau pembaruan versi bersyarat mencegah dua permintaan berhasil bersamaan; pemeriksaan ketersediaan dan penulisan berbagi batasan transaksi yang sama.

Langkah 7: Rancang pemulihan dan kasus saat tidak tersedia

Izinkan pengiriman ulang terbatas untuk keterlambatan pengiriman sambil membatalkan token lama. Jika alamat lama hilang, jangan terima alamat baru yang belum diverifikasi sebagai bukti pengambilalihan yang cukup; gunakan proses pemulihan akun yang lebih kuat. Kegagalan pengiriman, alamat yang sudah digunakan, dan penolakan kebijakan harus menampilkan pesan yang aman sambil tetap mempertahankan kode alasan internal dalam rekaman audit.

Langkah 8: Uji ancaman dan ukur hasil

Uji sesi yang dicuri, replay dan kedaluwarsa token, konfirmasi konkuren, pembatalan dari alamat lama, pencabutan refresh token, kepemilikan alamat lintas akun, dan enumerasi titik akhir. Ukur kegagalan step-up, percobaan replay, latensi dari konfirmasi hingga pencabutan, pengiriman notifikasi, dan volume pemulihan manual. Uji kebocoran basis data harus menunjukkan bahwa digest yang disimpan tidak dapat digunakan sebagai token.

Pertukaran (Trade-offs), batasan, dan perolehan informasi

TTL yang pendek mengurangi paparan risiko tetapi meningkatkan tekanan pengiriman ulang saat email tertunda; pembatasan pengiriman ulang dan status eksplisit menyeimbangkan keduanya. Mencabut setiap sesi lebih aman tetapi mengganggu kenyamanan di banyak perangkat, sehingga tingkatan risiko dapat menentukan cakupannya. Jendela pembatalan untuk alamat lama meningkatkan pemulihan tetapi tidak dapat membatalkan perubahan berisiko tinggi yang telah selesai.

Penyimpanan hanya-digest melindungi dari kebocoran basis data, tetapi token mentah masih dapat bocor melalui tautan, riwayat peramban, log, pelacakan (tracing), dan analitik. Saring jalur-jalur tersebut dan lakukan pengalihan (redirect) setelah penggunaan ke URL yang bersih. Batasan keunikan menyederhanakan kepemilikan identitas, tetapi produk harus mendefinisikan apakah satu alamat dapat dimiliki oleh beberapa akun.

Contoh jawaban berkualitas tinggi

"Saya akan memperlakukan perubahan email sebagai mesin status (state machine) berisiko tinggi. Pengguna menyelesaikan autentikasi ulang terbaru dan, jika diperlukan, pemeriksaan MFA yang ada. Alamat yang diajukan masuk ke rekaman tertunda; alamat saat ini tetap menjadi sumber otoritatif untuk proses masuk dan pemulihan. CSPRNG menghasilkan token sekali pakai dengan TTL pendek, sementara basis data hanya menyimpan digest, tujuan, versi, dan statusnya.

Transaksi konfirmasi mengunci akun dan permintaan, memeriksa digest, masa kedaluwarsa, versi, dan batasan keunikan, lalu secara atomik memperbarui alamat, menandai permintaan telah digunakan, dan mencatat peristiwa audit. Alamat lama menerima pemberitahuan keamanan dan dapat membatalkan permintaan yang masih tertunda. Setelah berhasil, refresh token dicabut dan sesi lain harus melakukan step-up kembali sesuai tingkat risiko.

Semua titik akhir menggunakan respons kesalahan yang seragam dan pembatasan laju berdasarkan akun, target, dan jaringan. Log berisi kode alasan, bukan token. Replay, race condition, hilangnya kotak surat lama, dan kegagalan pengiriman masing-masing memiliki jalur pemulihan yang pasti, dan pengujian mengukur masa kedaluwarsa token, latensi pencabutan, serta ketahanan terhadap enumerasi."

Kesalahan umum

  • Mengganti alamat langsung saat pengiriman formulir. Alamat yang belum terbukti dapat mengunci pengguna asli atau memungkinkan sesi yang dicuri mengambil alih akun.
  • Hanya mempercayai sesi yang ada. Pencuri sesi dapat menyelesaikan tindakan berisiko tinggi.
  • Menyimpan token mentah di basis data atau log. Sistem tersebut menjadi jalur pengambilalihan akun.
  • Mengizinkan penggunaan ulang token. Replay dapat mengulang notifikasi atau menimpa alamat.
  • Mengungkapkan keberadaan alamat. Respons konfirmasi dan permintaan menjadi celah untuk enumerasi akun.
  • Mengabaikan race condition pada keunikan. Dua akun atau permintaan dapat mengklaim alamat yang sama.
  • Mempertahankan semua sesi berumur panjang setelah berhasil. Refresh token yang dicuri tetap dapat digunakan.
  • Mempercayai alamat baru saat alamat lama hilang. Ini melewati jaminan pemulihan akun.

Pertanyaan lanjutan dan jawaban

Mengapa tidak menulis alamat baru terlebih dahulu lalu memverifikasinya secara asinkron?

Proses masuk, pemulihan, dan pemberitahuan dapat langsung menggunakannya, sementara pembatalan (rollback) memicu race condition. Menyimpan nilai tertunda secara terpisah menjaga input yang belum diverifikasi tetap berada di luar batas identitas.

Berapa lama masa berlaku token seharusnya?

Tidak ada angka mutlak yang terbebas dari konteks risiko. Pilih rentang waktu singkat berdasarkan distribusi pengiriman dan target ancaman, tambahkan batasan pengiriman ulang, dan ukur perilaku aktual dari penerbitan hingga kedaluwarsa.

Bisakah pemberitahuan alamat lama menggantikan MFA?

Tidak. Pemberitahuan dan pembatalan adalah pertahanan berlapis (defense-in-depth) dan sinyal pemulihan, bukan bukti identitas dengan jaminan tinggi. Akun berisiko tinggi tetap memerlukan metode MFA yang ada atau pemulihan yang lebih kuat.

Bagaimana jika dua tab melakukan konfirmasi secara bersamaan?

Gunakan versi, status sekali pakai, dan kunci transaksi sehingga hanya satu permintaan yang beralih dari status tertunda ke sudah digunakan. Permintaan kedua mengembalikan hasil idempoten dan tidak menimbulkan efek samping duplikat.

Bagaimana cara menjaga token agar tidak masuk ke analitik?

Gunakan jalur sekali pakai, saring parameter kueri di lapisan edge dan aplikasi, alihkan setelah digunakan ke URL yang bersih, dan nonaktifkan caching untuk respons sensitif.

Sumber publik

Pertanyaan terkait