~/VibeHandbook
PDF Gratis

Bab 18 · 04

Autentikasi vs otorisasi: endpoint yang bisa dipanggil siapa saja

Dua kata ini terdengar mirip dan perbedaannya adalah tempat di mana pelanggaran nyata terjadi.

  • Autentikasi adalah siapa kamu? — login, membuktikan identitas.
  • Otorisasi adalah apa yang diizinkan untuk kamu lakukan? — apakah pengguna yang sudah login ini boleh melakukan aksi ini pada data ini.

AI cukup baik dalam autentikasi; library menangani sebagian besarnya. Otorisasi adalah tempat AI rutin gagal, karena otorisasi bersifat spesifik terhadap aturan aplikasi kamu dan AI tidak mengetahuinya. Bencana khas dari buku teks:

// VULNERABLE: checks you're logged in, but not WHO you are
app.get("/admin/export-all-users", requireLogin, (req, res) => {
  res.json(db.getAllUsers()); // any logged-in user can hit this
});

itu "terlindungi" — kamu harus login. Tapi siapa pun pengguna yang sudah login, termasuk yang baru mendaftar tiga puluh detik lalu, bisa memanggilnya dan mengunduh data setiap pengguna. Autentikasi ada, otorisasi tidak ada. Perbaikannya adalah mengecek izin pada aksi itu sendiri:

// SAFE: confirms this user is actually an admin
app.get("/admin/export-all-users", requireLogin, (req, res) => {
  if (!req.user.isAdmin) return res.status(403).send("Forbidden");
  res.json(db.getAllUsers());
});

Bayangkan dua gerbang yang harus dilewati sebuah permintaan. Autentikasi bertanya "apakah kamu sudah login?"; otorisasi bertanya "apakah kamu diizinkan melakukan ini?" Pelanggaran terjadi ketika sebuah aplikasi membangun gerbang pertama dan melupakan gerbang kedua:

  request ──▶ ┌──────────────────┐  ──▶ ┌──────────────────┐  ──▶  action
              │ AUTHENTICATION   │      │ AUTHORIZATION     │       runs
              │ "logged in?"     │      │ "may THIS user    │
              │                  │      │  do THIS action?" │
              └──────────────────┘      └──────────────────┘
                  ✓ most apps              ✗ often missing
                    build this               → the breach

  EXAMPLE — /admin/export-all-users
     logged-in user  ──▶ [auth ✓] ──▶ [ no authz check ] ──▶ ALL users dumped
     logged-in user  ──▶ [auth ✓] ──▶ [ isAdmin? → 403  ] ──▶ blocked  ✓

Jebakan yang sama muncul dalam bentuk mini di mana-mana: sebuah endpoint yang mengembalikan pesanan #1234 tanpa mengecek apakah pesanan itu milik pengguna yang meminta. Siapa pun bisa mengubah nomor di dan membaca pesanan orang lain. Aturannya tidak glamor dan mutlak: cek otorisasi pada setiap endpoint yang menyentuh data, dan jangan percaya sebuah ID yang datang dari klien. Jangan mengira sebuah URL tersembunyi itu aman hanya karena tersembunyi — "tidak ada yang tahu ini ada" bukanlah kontrol keamanan.

Mau versi offline?

Unduh seluruh buku sebagai PDF atau EPUB — gratis.