Eskalasi Vertikal

Eskalasi hak istimewa vertikal melalui pemeriksaan level fungsi yang hilang dan endpoint admin tersembunyi.

Daftar isi

Eskalasi vertikal adalah keadaan ketika seorang pengguna memperoleh hak istimewa yang lebih tinggi daripada yang seharusnya, misalnya pengguna biasa yang dapat menjalankan fungsi admin. Topik ini membahas dua penyebab yang paling sering muncul, yaitu pemeriksaan level fungsi yang hilang dan endpoint admin yang hanya disembunyikan, lalu menunjukkan perbaikannya melalui gerbang role pada level fungsi. Simulasinya dijalankan dengan Python terhadap localhost sehingga seluruh skenario dapat direproduksi secara aman.

Pemeriksaan level halaman dan level fungsi#

Kontrol akses pada aplikasi web bekerja pada dua tingkat yang sering tertukar. Pemeriksaan level halaman memutuskan halaman mana yang boleh dibuka, misalnya menyembunyikan tautan panel admin dari menu. Pemeriksaan level fungsi (function-level access control) memutuskan apakah sebuah operasi di sisi server boleh dijalankan oleh pemohon, misalnya menghapus akun atau mengubah role (peran pengguna pada sistem). Keduanya perlu ada, tetapi yang menentukan keamanan data adalah pemeriksaan level fungsi karena permintaan dapat dikirim langsung ke server tanpa melewati halaman mana pun.

Endpoint admin yang tidak dicantumkan pada menu sering dianggap aman. Asumsi itu keliru karena URL tidak bersifat rahasia dan daftarnya dapat ditemukan lewat berkas JavaScript sisi klien, dokumen API, log, atau kamus kata pada alat pemindai. Begitu alamat diketahui, handler yang tidak memeriksa role akan mengeksekusi permintaan dari siapa pun yang mengirimkannya. Diagram berikut membandingkan permintaan yang sama pada dua versi aplikasi.

Tanpa pemeriksaan level fungsi (cacat)permintaan budiroutertanpa cek rolehandler adminakun terhapusoleh budiDengan pemeriksaan level fungsi (perbaikan)permintaan budirouterpemeriksaan rolerole adminhandler adminrole penggunarespons 403
Perbandingan pemeriksaan level fungsi yang hilang dan yang ada

Area admin sering dilindungi satu pemeriksaan pada tingkat konfigurasi, misalnya seluruh alamat di bawah /admin menuntut status masuk. Pemeriksaan semacam itu setara dengan level halaman karena menilai alamat permintaan, bukan operasinya. Dua handler di dalam area yang sama dapat menuntut hak berbeda, misalnya melihat log untuk editor dan menghapus akun untuk admin, sehingga satu konfigurasi direktori tidak mencukupi.

Simulasi endpoint admin tersembunyi#

Skrip berikut memodelkan rute /admin/hapus-akun yang tidak dicantumkan pada menu. Fungsi handle_admin_hapus_akun_cacat() langsung menghapus data tanpa melihat role pemanggil, sehingga budi yang hanya pengguna biasa dapat menghapus akun lain. Versi perbaikan membungkus handler yang sama dengan decorator butuh_role() yang menolak pemanggil tanpa role admin. Simpan berkas berikut sebagai eskalasi-vertikal.py, lalu jalankan dengan perintah python3 eskalasi-vertikal.py.

python eskalasi-vertikal.py
"""Simulasi eskalasi vertikal pada endpoint admin yang tersembunyi.

Rute /admin/hapus-akun tidak dicantumkan pada menu, tetapi versi cacat
tetap mengeksekusinya tanpa memeriksa role pemanggil. Versi perbaikan
memeriksa role pada level fungsi melalui decorator sebelum handler
dijalankan.
"""

AKUN = {
    "budi": {"role": "pengguna"},
    "sari": {"role": "admin"},
}

DATA_AKUN = []


def butuh_role(role_minimal):
    """Decorator yang menolak pemanggil dengan role di bawah minimum."""
    def hias(fungsi_tujuan):
        def pembungkus(pemanggil, *arg):
            if AKUN[pemanggil]["role"] != role_minimal:
                return 403, f"ditolak: butuh role '{role_minimal}'"
            return fungsi_tujuan(pemanggil, *arg)
        return pembungkus
    return hias


def handle_admin_hapus_akun_cacat(pemanggil, target):
    """Versi cacat: tidak ada pemeriksaan role sama sekali."""
    if target not in DATA_AKUN:
        return 404, f"akun '{target}' tidak ada"
    DATA_AKUN.remove(target)
    return 200, f"akun '{target}' dihapus"


@butuh_role("admin")
def handle_admin_hapus_akun_aman(pemanggil, target):
    """Versi perbaikan: pemeriksaan role dijalankan lebih dahulu."""
    if target not in DATA_AKUN:
        return 404, f"akun '{target}' tidak ada"
    DATA_AKUN.remove(target)
    return 200, f"akun '{target}' dihapus"


def jalankan(nama, handler):
    siapkan_data()
    print(f"== {nama} ==")
    for pemanggil, target in (("budi", "akun-lama"), ("sari", "akun-uji")):
        status, isi = handler(pemanggil, target)
        role = AKUN[pemanggil]["role"]
        print(f"{pemanggil} ({role}) memanggil /admin/hapus-akun target '{target}' -> {status} {isi}")
    print(f"data akun setelahnya: {DATA_AKUN}")


def siapkan_data():
    DATA_AKUN.clear()
    DATA_AKUN.extend(["akun-lama", "akun-uji"])


jalankan("Versi cacat: endpoint admin dieksekusi tanpa pemeriksaan role",
         handle_admin_hapus_akun_cacat)
print()
jalankan("Versi perbaikan: decorator memeriksa role sebelum eksekusi",
         handle_admin_hapus_akun_aman)
text Keluaran
== Versi cacat: endpoint admin dieksekusi tanpa pemeriksaan role ==
budi (pengguna) memanggil /admin/hapus-akun target 'akun-lama' -> 200 akun 'akun-lama' dihapus
sari (admin) memanggil /admin/hapus-akun target 'akun-uji' -> 200 akun 'akun-uji' dihapus
data akun setelahnya: []

== Versi perbaikan: decorator memeriksa role sebelum eksekusi ==
budi (pengguna) memanggil /admin/hapus-akun target 'akun-lama' -> 403 ditolak: butuh role 'admin'
sari (admin) memanggil /admin/hapus-akun target 'akun-uji' -> 200 akun 'akun-uji' dihapus
data akun setelahnya: ['akun-lama']

Pada versi cacat, kedua pemanggil berhasil menghapus akun, termasuk budi yang hanya pengguna biasa. Tidak ada pemeriksaan apa pun di antara router dan handler, sehingga mengetahui alamat URL sama artinya memiliki akses. Inilah eskalasi vertikal, yaitu kenaikan hak istimewa yang terjadi tanpa memperoleh kredensial admin sekalipun. Pada versi perbaikan, decorator menjawab sebelum handler dijalankan, permintaan budi berhenti dengan 403, dan permintaan sari tetap berhasil karena rolenya memenuhi syarat.

Perbaikan: gerbang role pada level fungsi#

Pemeriksaan role perlu ditempatkan sedekat mungkin dengan operasi yang dilindungi dan dijalankan melalui satu mekanisme terpusat, misalnya decorator pada Python, middleware pada framework backend, atau anotasi otorisasi bawaan framework. Penerapan yang tersebar dan ditulis secara manual pada tiap handler cepat terlewat ketika endpoint baru ditambahkan. Prinsip dasarnya tetap deny by default, yaitu handler menolak pemanggil sampai role pemanggilnya terbukti memenuhi syarat. Peta endpoint beserta role minimumnya perlu ditinjau ulang setiap kali ada perubahan fitur.

Pemeriksaan level fungsi juga berlaku untuk endpoint API yang tidak memiliki halaman sama sekali. Permintaan terhadap API datang langsung dengan metode seperti POST atau DELETE, sehingga konsep menu dan halaman bahkan tidak relevan di sana. Satu-satunya pertahanan yang berarti adalah pemeriksaan role sebelum logika bisnisnya dieksekusi.

Pemeriksaan yang tepat menilai role pemanggil pada setiap permintaan, bukan sekali pada saat masuk. Status masuk dapat berlangsung berjam-jam, sedangkan role dapat dicabut kapan saja, sehingga keputusan otorisasi harus mengambil nilai terkini di sisi server. Sistem yang memiliki beberapa tingkat role juga lebih aman menggunakan hierarki, misalnya admin mencakup editor dan editor mencakup pengguna, daripada membandingkan nilai persis seperti pada simulasi. Yang penting adalah keputusannya berada di satu tempat sehingga celahnya mudah diaudit.

Kesalahan umum#

Kesalahan berikut muncul ketika kontrol akses level fungsi dirancang seadanya.

  • Mengandalkan penyembunyian URL atau menu. Penemuan alamat hanya soal waktu, sehingga handler tetap harus memeriksa role sendiri.
  • Memeriksa role hanya pada antarmuka klien. Tombol yang disembunyikan tidak menghilangkan endpoint-nya, dan permintaan tetap dapat dibuat langsung.
  • Menggunakan satu pemeriksaan untuk seluruh area admin. Fungsi yang berbeda dapat menuntut role berbeda, sehingga pemeriksaan ditempatkan per fungsi, bukan per direktori.
  • Menambah endpoint baru tanpa meninjau otorisasi. Endpoint yang terlewat oleh gerbang role langsung menjadi pintu eskalasi vertikal.

Ringkasan#

  • Eskalasi vertikal terjadi ketika fungsi berhak istimewa dijalankan tanpa pemeriksaan role pada level fungsi.
  • URL admin yang tersembunyi bukan kontrol akses karena alamat dapat ditemukan dan dipanggil langsung.
  • Perbaikannya adalah gerbang role terpusat yang menolak secara baku dan diterapkan pada setiap fungsi sensitif.

Referensi#