Skip to content

Satu Akun Admin per Bidang agar Uji RBAC Terbukti

Adityo Guni Waluyo

Pemeriksaan izin per bidang mentok karena tidak ada akun admin yang cocok. Satu CLI tertutup membuat satu akun per bidang dan membuktikannya lewat login.

Ringkasan

Saya harus membuat akun admin untuk setiap bidang. Akun itu dibuat dengan perintah create-bidang-users yang aman. Perintah itu hanya berjalan di environment development.

Saya menatap layar CMS KotaPortal pagi itu dengan satu tugas: memeriksa apakah menu baru hanya muncul untuk bidang yang benar. Pengecekan mentok di menit pertama. Akun demo berrole user ditolak gerbang otorisasi, sementara satu-satunya akun yang bisa masuk adalah superadmin. Dengan akun itu semua halaman terbuka, dan justru di situ buktinya hilang: tidak ada layar yang tertutup untuk dibandingkan, sehingga satu tampilan yang berhasil tidak menyatakan apa-apa tentang aturan per bidang.

Tebakan pertama saya sederhana. Pakai saja akun superadmin yang sudah ada, atau akun demo yang perannya dibatasi. Dua-duanya tidak cocok. Superadmin lolos karena memang tidak ada batas yang bisa diuji, sedangkan akun demo berperan terbatas sengaja tidak memegang hak admin. Uji otorisasi membutuhkan hak yang tepat, bukan hak yang dihindari.

Yang saya butuhkan satu akun admin untuk setiap bidang, dibuat dengan cara yang mustahil menyeberang ke tempat lain.

Satu Akun untuk Satu Bidang

Authorization berbeda dari authentication: yang pertama memastikan bahwa tindakan yang diminta disetujui untuk entitas tertentu, yang kedua hanya memastikan identitas [1]. Orang yang sudah login belum otomatis berhak atas setiap resource. Posisi saya tadi persis di titik itu, terautentikasi penuh tetapi belum terbukti terotorisasi.

OWASP menerjemahkan cara berpikir itu menjadi satu tabel: satu authorization biasanya punya dua dimensi, fitur dan role logis, dan keduanya didaftar dalam authorization matrix [6]. Di matriks itu pilihan desainnya jadi jelas. Kalau aturan dibaca per bidang, akun ujinya juga harus ada per bidang. Satu akun superadmin memadatkan seluruh role jadi satu titik sehingga tidak ada garis yang bisa diperiksa.

Ada keberatan wajar terhadap resep ini: bukankah akun admin seragam justru pola yang diperingatkan OWASP? A07:2021 menyebut aplikasi lemah bila mengizinkan sandi bawaan atau yang dikenal umum, dan anjurannya tegas: jangan mengirim atau men-deploy kredensial bawaan, khususnya untuk pengguna admin [2]. Jawabannya ada pada lokasi pembuatan. Akun ini tidak dikirim ke mana pun: ia dibuat oleh perintah yang dijalankan manual, hanya di database development, dengan data tabel users yang memang tidak ikut mekanisme sinkronisasi database antar-environment.

Di proyek itu juga ada aturan lama yang tampak bertentangan: akun development tidak boleh dijadikan admin, karena login otomatis untuk pengujian end-to-end sebaiknya tetap berperan terbatas. Keduanya melayani hal berbeda. Login otomatis hanya butuh identitas yang sah untuk melewati formulir, sedangkan pemeriksaan izin butuh hak yang berbeda per bidang. Yang berbahaya bukan akun admin development, melainkan akun admin yang bisa tercipta di environment yang salah.

Tiga Kunci pada CLI yang Menulis Baris Admin

Perintah create-bidang-users saya buat karena menulis baris admin bukan pekerjaan yang boleh dilakukan skrip kapan pun. Tiga pengaman mengelilinginya, dan urutannya tidak kebetulan.

Pertama, kunci environment. Nilai APP_ENV dibaca persis seperti adanya dan harus sama dengan development; variabel yang kosong, tidak terpasang, atau salah eja membuat perintah berhenti sebelum menyentuh database. Go sendiri membedakan nilai kosong dan variabel yang tidak ada, sehingga aturan "tidak ada konfigurasi berarti menolak" bisa ditulis tanpa tebakan [4]. Prinsip 12factor menguatkan arah yang sama: konfigurasi hidup di environment variable dan tidak pernah dikelompokkan menjadi "environments" bernama, karena pengelompokan semacam itu makin rapuh seiring bertambahnya deploy [3].

Pertama, kunci environment. Perintah dijalankan hanya dengan satu syarat:

APP_ENV=development go run ./cmd/create-bidang-users

Nilai APP_ENV dibaca persis seperti adanya dan harus sama dengan development; variabel yang kosong, tidak terpasang, atau salah eja membuat perintah berhenti sebelum menyentuh database. Go sendiri membedakan nilai kosong dan variabel yang tidak ada, sehingga aturan "tidak ada konfigurasi berarti menolak" bisa ditulis tanpa tebakan [4]. Prinsip 12factor menguatkan arah yang sama: konfigurasi hidup di environment variable dan tidak pernah dikelompokkan menjadi "environments" bernama, karena pengelompokan semacam itu makin rapuh seiring bertambahnya deploy [3].

Lalu datang allowlist baris. Alat ini hanya membuat tepat satu akun admin untuk setiap assignment users.bidang yang terdaftar, dan menolak menyentuh akun mana pun yang role-nya bukan admin. Batasnya diletakkan pada data yang boleh diubah, bukan pada niat orang yang menjalankan.

Terakhir, pemeriksaan diri. Setiap akun yang baru dibuat dibaca ulang dari database: hash sandi cocok, role sesuai, bidang sesuai, dan flag verified terisi. bcrypt memberi jawaban yang tegas untuk itu. CompareHashAndPassword mengembalikan ErrMismatchedHashAndPassword ketika sandi dan hash tidak cocok [5], jadi kegagalan verifikasi terbaca sebagai kegagalan, bukan sebagai asumsi.

Bukti terakhir bukan log, melainkan login. Endpoint login publik memang hanya menerima role user, jadi staf masuk lewat login CMS dan menerima JWT beserta daftar permission-nya. Satu akun hasil perintah tadi saya jalankan terhadap login CMS, JWT-nya kembali lengkap dengan izinnya, dan pemeriksaan manual bisa dilanjutkan: masuk dengan akun bidang, buka menu yang seharusnya tersedia, lalu coba menu bidang lain dan pastikan ditolak.

Sejak itu cara saya menilai alat sekali jalan berubah. Bukan dari sedikitnya baris yang disentuh, melainkan dari perilakunya saat kondisi tidak sesuai. Alat yang berhenti sendiri justru membuat saya berani menjalankannya lagi.

Sumber:

Sources

[1] https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html

[2] https://owasp.org/Top10/2021/A07_2021-Identification_and_Authentication_Failures

[3] https://12factor.net/config

[4] https://raw.githubusercontent.com/golang/go/master/src/os/env.go

[5] https://raw.githubusercontent.com/golang/crypto/master/bcrypt/bcrypt.go

[6] https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Testing_Automation_Cheat_Sheet.html

Artikel terkait