Beberapa waktu lalu, saya menangani kasus spam yang cukup membingungkan. Sebuah akun email di lingkungan Carbonio milik klien tiba tiba dipakai mengirim spam ke alamat luar negeri, padahal 2FA sudah diaktifkan di akun tersebut. Pertanyaan pertama yang muncul jelas, kalau 2FA sudah nyala, kok masih bisa kebobolan?
Jawabannya ternyata bukan soal 2FA-nya yang lemah, tapi soal bagaimana Carbonio memperlakukan otentikasi ketika domain tersebut terhubung ke Active Directory. Tulisan ini saya buat supaya kalian yang mengelola Carbonio dengan integrasi AD, terutama yang mengaktifkan 2FA, tahu persis di mana titik rawannya.
Kondisi Awal, Domain Terhubung ke AD dengan Fallback Aktif
Skenario yang umum dipakai banyak instansi. Domain Carbonio diarahkan otentikasinya ke Active Directory lewat atribut zimbraAuthMech yang diisi ad, dengan zimbraAuthFallbackToLocal diisi TRUE supaya kalau AD sedang bermasalah, user masih bisa masuk pakai password lokal Carbonio sebagai cadangan.
Di atas kertas ini kedengaran aman. Tapi begitu saya coba reproduksi di lingkungan lab yang persis meniru struktur produksi, ada beberapa masalah yang muncul.
Masalah Pertama, Dua Password yang Sama Sama Valid
Karena fallback aktif, satu akun ternyata punya dua password yang sama sama valid, password AD asli, dan password lokal Carbonio yang tersimpan sejak akun dibuat. Kalau penyerang berhasil mendapatkan salah satunya saja, dia tetap bisa masuk, entah lewat webmail maupun lewat SMTP untuk mengirim email.
Ini saya buktikan langsung memakai swaks ke port submission (587). Dua duanya, password AD maupun password lokal, sama sama diterima dengan status 235 Authentication successful.
Masalah tambahan dari kondisi ini. Begitu insiden terjadi, kalian tidak bisa langsung tahu password mana yang bocor hanya dari log SMTP. Log cuma mencatat username, bukan lewat jalur otentikasi mana password itu tervalidasi.
Masalah Kedua, AD Auth Membuat 2FA di SMTP Benar Benar Diabaikan
Ini bagian yang menurut saya paling perlu diketahui pengguna Carbonio yang pakai AD auth, dan justru yang paling penting dari semua temuan.
Saya aktifkan 2FA sungguhan di akun test (OTP asli tergenerate, bukan cuma flag kosong), lalu saya set kebijakan SMTP supaya menuntut 2FA kecuali dari jaringan tertentu yang dipercaya. Dengan zimbraAuthMech masih diisi ad, saya coba SMTP dari IP yang jelas jelas tidak masuk daftar percaya. Hasilnya, email tetap terkirim, tanpa hambatan apa pun. Log mailboxd bahkan tidak menunjukkan satu baris pun pengecekan kebijakan 2FA yang berjalan.
Sebagai pembanding, saya matikan integrasi AD (atribut zimbraAuthMech dikosongkan, jadi Carbonio pakai otentikasi lokalnya sendiri), dengan kondisi 2FA dan kebijakan SMTP yang persis sama. Kali ini Carbonio menolak dengan tegas:
Authorization error: Unsupported 2FA for service Smtp
Perbandingan ini menunjukkan sesuatu yang jelas. Mekanisme otentikasi native Carbonio sebenarnya sudah benar. Begitu 2FA aktif tapi protokolnya (SMTP) tidak bisa menampilkan tantangan OTP, Carbonio menolak permintaan itu daripada meloloskannya begitu saja. Yang bermasalah justru jalur otentikasi eksternal ke AD, jalur itu sama sekali tidak melewati pengecekan kebijakan 2FA untuk SMTP.
Dengan kata lain, kalau domain kalian pakai AD auth, 2FA yang kalian aktifkan di akun user secara efektif hanya berlaku untuk webmail, tidak untuk SMTP, IMAP, maupun POP, meskipun kebijakan sudah diatur mewajibkannya.
Kenapa Solusi Matikan Saja AuthMech Juga Tidak Aman
Opsi yang kelihatannya masuk akal adalah mengosongkan zimbraAuthMech sambil menonaktifkan fallback lokal, supaya Carbonio dipaksa memakai jalur otentikasi yang benar tadi. Saya coba juga skenario ini di lab.
Menariknya, walau zimbraAuthMech dikosongkan, Carbonio ternyata tetap memvalidasi password lewat AD, selama atribut zimbraAuthLdapURL dan bind DN-nya masih terisi. Password lokal Carbonio memang berhasil ditolak sesuai harapan.
Tapi begitu kebijakan 2FA untuk SMTP diaktifkan kembali, password AD yang tadi berhasil justru langsung ditolak, dengan pesan invalid credentials, padahal passwordnya sama persis dan tidak diubah. Dari log terlihat jelas permintaan ini lewat modul otentikasi baru yang punya implementasi bind ke AD sendiri, terpisah dari konfigurasi lama, dan implementasi itu gagal.
Ini persis gejala yang membuat banyak pengelola Carbonio terpaksa membatalkan perubahan semacam ini di produksi. Begitu diterapkan, seluruh user yang pakai mail client seperti Outlook langsung tidak bisa login sama sekali, dianggap password salah padahal tidak ada yang berubah.
Kenapa AD Tetap Tersambung Padahal AuthMech-nya Sudah Dikosongkan
Temuan ini saya kejar lebih lanjut karena kedengarannya janggal. Kalau atribut yang mengatur mekanisme otentikasi sudah kosong, kenapa Carbonio masih mau mengecek ke AD?
Saya buktikan dengan mengisolasi variabel satu per satu. Ketika zimbraAuthMech kosong tapi zimbraAuthLdapURL masih terisi, password AD tetap diterima. Begitu zimbraAuthLdapURL saya kosongkan juga, barulah password AD ditolak.
Artinya, Carbonio tidak murni mengandalkan satu atribut untuk memutuskan jalur otentikasi. Selama detail koneksi LDAP domain (URL dan bind DN) masih terisi, Carbonio tetap mencoba menyambung ke situ, terlepas dari status atribut mekanisme otentikasinya. Ini kemungkinan besar bukan perilaku yang sengaja didokumentasikan, melainkan efek samping dari cara Carbonio mendeteksi konfigurasi domain. Bagi pengelola yang mengikuti saran mengosongkan mekanisme otentikasi saja tanpa ikut membersihkan detail koneksi LDAP-nya, hasilnya jadi ambigu. Domain kelihatan seperti sudah lepas dari AD, padahal diam diam masih tersambung, dan kondisi campur aduk semacam ini yang kemungkinan memicu kegagalan modul otentikasi baru seperti yang dijelaskan di bagian sebelumnya.
Application Specific Password, Satu Satunya yang Benar Benar Berfungsi
Setelah menemukan berbagai celah dan bug di atas, saya coba satu hal lagi. Bagaimana kalau, alih alih memakai password akun biasa, SMTP diautentikasi memakai application specific password yang memang disediakan Carbonio untuk keperluan semacam ini?
Saya uji di kondisi paling bermasalah sekalipun, yaitu saat AuthMech kosong, fallback nonaktif, dan kebijakan 2FA SMTP aktif, kondisi yang di bagian sebelumnya membuat password AD maupun password lokal biasa sama sama ditolak. Saya generate application specific password khusus untuk layanan SMTP, lalu coba autentikasi memakainya.
Hasilnya berhasil, email terkirim tanpa masalah. Application specific password ini ternyata sepenuhnya independen dari semua bug yang saya temukan sebelumnya, tidak peduli AuthMech-nya kosong, mengarah ke AD, atau berada di kondisi ambigu sekalipun. Ini menjadikannya satu satunya mitigasi yang benar benar konsisten dari semua yang saya uji.
Ringkasan Perbandingan
| Konfigurasi | Password AD | Password lokal | Application specific password |
|---|---|---|---|
| AuthMech ad, fallback aktif, 2FA mati | Berhasil | Berhasil | Belum diuji |
| AuthMech ad, fallback aktif, 2FA aktif di SMTP | Berhasil, 2FA diabaikan total | Berhasil, celah ganda | Belum diuji |
| AuthMech kosong, fallback mati, 2FA mati | Berhasil | Ditolak | Belum diuji |
| AuthMech kosong, fallback mati, 2FA aktif di SMTP | Ditolak, invalid credentials | Ditolak | Berhasil |
Yang Bisa Kalian Lakukan Sekarang
Berdasarkan semua temuan di atas, ini yang saya sarankan untuk pengelola Carbonio yang memakai AD auth.
- Jangan andalkan kombinasi AuthMech kosong plus fallback mati sebagai solusi tunggal. Kalau tetap ingin memakainya, pastikan detail koneksi LDAP domain (URL dan bind DN) ikut dikosongkan juga, supaya domain benar benar lepas dari AD dan tidak berada di kondisi ambigu.
- Langkah paling praktis untuk saat ini tanpa mengubah banyak hal. Biarkan atribut
zimbraAuthMechtetap diisiad, tapi matikanzimbraAuthFallbackToLocal. Ini menutup celah password ganda tanpa memicu bug jalur otentikasi baru, walau harus disadari bahwa celah 2FA di SMTP belum benar benar tertutup dengan cara ini. - Wajibkan application specific password untuk semua akses SMTP, IMAP, dan POP. Dari semua yang saya uji, ini satu satunya cara yang benar benar konsisten memastikan password akun biasa, baik dari AD maupun lokal, tidak lagi bisa dipakai di protokol yang memang tidak mendukung tantangan OTP.
- Kalau kalian mengelola Carbonio dengan setup serupa, sebaiknya cek juga apakah 2FA kalian benar benar berlaku di SMTP, jangan asumsikan aktifnya toggle di panel admin berarti semua protokol sudah terlindungi.
Saya akan melaporkan temuan temuan di atas ke tim Zextras sebagai laporan terpisah, karena sifatnya lebih spesifik dari sekadar SMTP tidak mendukung 2FA yang selama ini jadi penjelasan umum.