Skip to main content

Command Palette

Search for a command to run...

Ketika RBAC Salah: Studi Kasus Keamanan untuk Full-Stack Developer

Published
6 min read
Ketika RBAC Salah: Studi Kasus Keamanan untuk Full-Stack Developer
A

I am an enthusiastic researcher and developer with a passion for using technology to innovate in business and education.

Beberapa waktu lalu muncul sebuah write-up bug bounty berjudul How a Simple RBAC Mistake Led to a $20K+ Admin Takeover yang dipublikasikan oleh seorang security researcher. Kasus ini menunjukkan sesuatu yang sangat menarik: kerentanan yang menyebabkan takeover sistem bukan berasal dari eksploitasi kompleks, melainkan dari kesalahan logika sederhana dalam kontrol akses.

Kesalahan tersebut terjadi pada implementasi Role-Based Access Control (RBAC). Backend hanya memvalidasi bahwa token pengguna valid, tetapi tidak memverifikasi apakah pengguna tersebut memiliki hak akses yang sesuai.

Akibatnya, pengguna biasa dapat memanggil endpoint admin secara langsung dan bahkan mengubah rolenya menjadi Super Admin.

Kasus ini memberikan pelajaran penting bagi para full-stack developer:

Authentication bukanlah Authorization.

Login yang berhasil tidak berarti pengguna boleh melakukan semua aksi dalam sistem.

Dalam artikel ini kita akan membahas:

  • studi kasus kerentanan RBAC

  • contoh implementasi yang buruk

  • contoh implementasi yang aman

  • contoh mini project API menggunakan Hono


Studi Kasus: Bagaimana Sistem Bisa Diambil Alih

Dalam kasus tersebut, sistem memiliki arsitektur seperti ini:

Mobile App
     │
     │
 Shared API Backend
     │
 ┌───────────────┐
 │ Admin Portal  │
 │ Invoice Portal│
 └───────────────┘

Mobile app menyediakan fitur registrasi user.

Setelah user mendaftar, sistem memberikan token autentikasi.

Masalah muncul karena backend hanya melakukan pemeriksaan:

token valid → allow request

tanpa memverifikasi role.

Peneliti keamanan kemudian mencoba mengakses endpoint admin menggunakan token user biasa:

GET /user/v2/users
GET /user/v2/acl
POST /user/v2/acl

Karena tidak ada validasi role, request tersebut berhasil.

Lebih buruk lagi, terdapat endpoint yang memungkinkan perubahan role:

POST /user/v2/acl

Dengan payload sederhana:

{
  "role": "super_admin"
}

Pengguna biasa berhasil menaikkan hak aksesnya menjadi Super Admin.

Dari titik ini, ia dapat:

  • membaca seluruh data pengguna

  • mengubah role pengguna lain

  • mengontrol konfigurasi sistem

  • mengakses beberapa portal admin sekaligus

Kerentanan ini menghasilkan bug bounty lebih dari $20.000.


Kesalahan Arsitektur yang Sering Terjadi

Beberapa pola kesalahan yang sering muncul pada aplikasi modern:

1. Backend hanya memvalidasi token

Developer sering membuat middleware seperti:

if token valid:
   allow request

Padahal seharusnya:

if token valid AND role authorized:
   allow request

2. Menganggap UI sebagai layer keamanan

Contoh kesalahan:

  • menu admin disembunyikan

  • tombol admin tidak muncul

  • route admin tidak ditampilkan

Namun endpoint API masih dapat dipanggil langsung menggunakan tools seperti:

  • Postman

  • Burp Suite

  • curl


3. API dipakai oleh banyak aplikasi

Backend sering dipakai oleh:

  • mobile app

  • admin dashboard

  • internal tools

Jika RBAC tidak dirancang dengan baik, maka token dari satu aplikasi bisa digunakan untuk mengakses sistem lain.


Contoh Project Buruk (Broken RBAC)

Berikut contoh mini API menggunakan Hono yang memiliki masalah yang sama seperti studi kasus tadi.

Struktur sederhana project:

src
 ├─ server.ts
 ├─ auth.ts
 └─ db.ts

Middleware Authentication

import { verify } from "jsonwebtoken"

export const auth = async (c, next) => {
  const token = c.req.header("Authorization")

  if (!token) {
    return c.json({ error: "Unauthorized" }, 401)
  }

  try {
    const payload = verify(token, process.env.JWT_SECRET)
    c.set("user", payload)

    await next()
  } catch {
    return c.json({ error: "Invalid token" }, 401)
  }
}

Middleware ini hanya memastikan user login.


Endpoint Admin (Tidak Aman)

GET /admin/users

Implementasi:

app.get("/admin/users", auth, async (c) => {
  return c.json(await db.users.findMany())
})

Masalahnya:

tidak ada validasi role.

Jika user biasa memiliki token valid, ia tetap bisa mengakses endpoint ini.


Endpoint Role Update (Sangat Berbahaya)

POST /admin/role

Implementasi buruk:

app.post("/admin/role", auth, async (c) => {
  const body = await c.req.json()

  await db.users.update({
    where: { id: body.userId },
    data: { role: body.role }
  })

  return c.json({ success: true })
})

Attacker bisa mengirim request:

{
 "userId": 15,
 "role": "super_admin"
}

Jika backend tidak memverifikasi role:

user → super_admin

Inilah privilege escalation.


Versi Project yang Aman

Sekarang kita perbaiki implementasinya.

Kita pisahkan antara:

  • authentication

  • authorization


Middleware Role Check

export const requireRole = (role) => {
  return async (c, next) => {
    const user = c.get("user")

    if (!user || user.role !== role) {
      return c.json({ error: "Forbidden" }, 403)
    }

    await next()
  }
}

Middleware ini memastikan hanya role tertentu yang boleh mengakses endpoint.


Endpoint Admin Aman

GET /admin/users

Implementasi:

app.get(
  "/admin/users",
  auth,
  requireRole("admin"),
  async (c) => {
    return c.json(await db.users.findMany())
  }
)

Sekarang alurnya:

request
 ↓
auth middleware
 ↓
role validation
 ↓
endpoint handler

User biasa akan mendapatkan:

403 Forbidden

Endpoint Role Update Aman

Endpoint ini sangat sensitif sehingga hanya boleh diakses oleh super admin.

app.post(
  "/admin/role",
  auth,
  requireRole("super_admin"),
  async (c) => {

    const body = await c.req.json()

    await db.users.update({
      where: { id: body.userId },
      data: { role: body.role }
    })

    return c.json({ success: true })
  }
)

Sekarang user biasa tidak dapat mengubah role.


Praktik Terbaik untuk Developer

Beberapa prinsip penting ketika membangun API:

1. Backend adalah sumber keamanan

Frontend tidak boleh dipercaya.

Semua kontrol akses harus dilakukan di backend.


2. Setiap endpoint harus memiliki aturan akses

Contoh:

Endpoint Role
/users/me user
/admin/users admin
/admin/role super_admin

3. Gunakan prinsip Least Privilege

User hanya boleh melakukan hal yang benar-benar dibutuhkan.


4. Uji API seperti hacker

Cobalah:

  • akses endpoint admin dengan user biasa

  • ubah parameter request

  • gunakan Postman untuk bypass UI

Tes sederhana ini sering menemukan bug besar.


Kesimpulan

Kasus bug bounty tersebut menunjukkan satu hal yang sangat penting dalam pengembangan aplikasi modern.

Kerentanan terbesar sering kali bukan berasal dari eksploitasi kompleks, tetapi dari kesalahan logika sederhana dalam kontrol akses.

Kesalahan kecil seperti ini:

if token valid → allow

seharusnya ditulis:

if token valid AND role authorized → allow

Perbedaan kecil tersebut dapat menentukan apakah sistem Anda aman atau justru dapat diambil alih oleh attacker.

Sebagai full-stack developer, kita tidak hanya bertanggung jawab membuat aplikasi berjalan dengan baik, tetapi juga memastikan aplikasi tersebut tidak mudah disalahgunakan.

Karena dalam keamanan aplikasi, sering kali:

Bug paling berbahaya adalah bug yang terlihat paling sederhana.

Sumber Inspirasi: https://medium.com/@Seek404/how-a-simple-rbac-mistake-led-to-a-20k-admin-takeover-d196694791dd

More from this blog

F

Finlup ID | Sharing dunia teknologi dan coding

206 posts

Membedah Tren dan Teknologi yang Mengubah Dunia.