💡 Key Takeaways
- Authentication and Authorization: The Foundation That Everyone Rushes Past
- Request Validation: Where Most Bugs Actually Live
- Response Validation: Trust, But Verify
- State Management and Idempotency: The Subtle Art of Consistency
Tiga tahun yang lalu, saya menyaksikan API produksi gagal secara spektakuler pada pukul 2 pagi karena tidak ada yang menguji apa yang terjadi ketika Anda mengirimkan bidang tanggal yang diformat sebagai "32/13/2021." Runtuhnya sangat indah dengan cara yang paling buruk: 47.000 transaksi gagal, pelanggan marah memenuhi saluran dukungan, dan seorang CEO yang menginginkan jawaban yang tidak saya miliki. Malam itu mengubah cara saya mendekati pengujian API selamanya.
💡 Poin Penting
- Otentikasi dan Otorisasi: Dasar yang Dilalui Semua Orang
- Validasi Permintaan: Di Mana Sebagian Besar Bug Sebenarnya Berasal
- Validasi Respons: Percaya, Tapi Verifikasi
- Manajemen Status dan Idempotensi: Seni Halus Konsistensi
Saya adalah Sarah Chen, dan saya telah menjadi insinyur otomatisasi QA selama delapan tahun terakhir, lima tahun terakhir berfokus secara eksklusif pada pengujian API untuk platform fintech dan kesehatan. Saya telah menguji segalanya dari endpoint CRUD sederhana hingga API pemrosesan pembayaran yang kompleks yang menangani jutaan dolar setiap hari. Apa yang saya pelajari adalah ini: sebagian besar kegagalan API bukanlah kasus tepi eksotis—mereka adalah masalah yang dapat diprediksi yang akan ditangkap oleh daftar periksa sistematis.
Daftar periksa yang saya bagikan hari ini adalah yang tepat yang saya gunakan untuk setiap endpoint yang saya uji. Ini telah menyelamatkan tim saya dari setidaknya selusin insiden produksi hanya dalam setahun terakhir, dan ini membantu kami mempertahankan uptime 99,97% di lebih dari 230 endpoint API. Ini bukan teori—ini adalah kenyataan yang teruji dalam pertempuran dari seseorang yang telah dipanggil pada jam 3 pagi lebih sering daripada yang ingin saya ingat.
Otentikasi dan Otorisasi: Dasar yang Dilalui Semua Orang
Ini adalah statistik yang seharusnya membuat Anda takut: dalam pengalaman saya mengaudit API di tujuh perusahaan berbeda, kira-kira 60% memiliki setidaknya satu endpoint dengan logika otorisasi yang rusak. Bukan otentikasi—otorisasi. Endpoint tersebut memverifikasi bahwa Anda sudah masuk, tetapi tidak memeriksa dengan benar apakah Anda seharusnya mengakses sumber daya spesifik itu.
Daftar periksa otentikasi dan otorisasi saya dimulai dengan hal-hal dasar yang jelas namun sering terlewat:
- Uji tanpa token otentikasi sama sekali—harus mengembalikan 401
- Uji dengan token kedaluwarsa—harus mengembalikan 401, bukan 500
- Uji dengan token yang tidak terformat dengan benar—harus mengembalikan 401, tidak macet
- Uji dengan token yang valid tetapi izin yang salah—harus mengembalikan 403
- Uji dengan token untuk pengguna yang berbeda yang mencoba mengakses sumber daya pengguna lain
Yang terakhir ini adalah di mana semuanya menjadi menarik. Saya pernah menemukan endpoint di mana Anda bisa mengambil riwayat pembayaran pengguna mana pun hanya dengan mengubah ID pengguna di URL, meskipun Anda sedang masuk sebagai pengguna yang berbeda. Endpoint tersebut memeriksa apakah Anda sudah masuk, tetapi tidak pernah memverifikasi apakah ID pengguna yang diminta cocok dengan ID pengguna yang sudah terautentikasi. Ini disebut Referensi Objek Langsung yang Tidak Aman (IDOR), dan ini sangat umum.
Saya juga secara eksplisit menguji alur penyegaran token. Apa yang terjadi ketika token kedaluwarsa di tengah permintaan? Apakah API Anda menangani dengan baik, atau apakah itu meninggalkan klien dalam keadaan aneh? Saya telah melihat sistem di mana token kedaluwarsa selama permintaan POST akan mengembalikan 401, tetapi data masih sebagian ditulis ke basis data. Itu adalah mimpi buruk untuk konsistensi data.
Untuk API yang menggunakan kunci API alih-alih token, saya memverifikasi rotasi kunci berfungsi dengan benar. Dapatkah Anda menghasilkan kunci baru? Apakah kunci lama langsung berhenti berfungsi, atau apakah ada periode grace? Apakah periode grace tersebut didokumentasikan? Saya pernah bekerja dengan API di mana rotasi kunci memiliki periode tumpang tindih 24 jam yang tidak ada yang tahu, menyebabkan kegagalan audit keamanan.
Matriks otorisasi adalah senjata rahasia saya di sini. Saya membuat spreadsheet dengan setiap endpoint di satu sumbu dan setiap peran pengguna di sumbu lainnya. Kemudian saya secara sistematis menguji setiap kombinasi. Ini membosankan, tetapi berhasil menangkap bug otorisasi di 100% proyek di mana saya menerapkannya. Ya, 100%. Itu bukan hiperbola—setiap proyek memiliki setidaknya satu endpoint di mana logika otorisasi salah untuk setidaknya satu peran.
Validasi Permintaan: Di Mana Sebagian Besar Bug Sebenarnya Berasal
Jika saya harus menebak di mana 70% bug API berasal, itu akan berada di validasi permintaan. Pengembang adalah makhluk yang optimis—mereka menulis kode dengan asumsi input akan masuk akal. Namun internet tidak masuk akal, begitu juga sistem yang memanggil API Anda.
Daftar periksa validasi permintaan saya sangat lengkap karena memang harus demikian:
- Kirim tubuh permintaan yang sepenuhnya kosong—apa yang terjadi?
- Kirim null untuk setiap bidang yang wajib secara individu
- Kirim string kosong untuk bidang string
- Kirim string yang hanya mengandung spasi
- Kirim string yang terlalu panjang 1 karakter untuk batas panjang apa pun
- Kirim string yang terlalu panjang 1000 kali
- Kirim angka negatif untuk bidang yang mengharapkan bilangan bulat positif
- Kirim nol untuk bidang di mana nol mungkin tidak valid
- Kirim angka desimal untuk bidang integer
- Kirim angka yang sangat besar (uji untuk overflow integer)
- Kirim angka yang sangat kecil (uji untuk underflow)
- Kirim karakter khusus di bidang string: kutipan, backslash, byte nol, Unicode
- Kirim upaya injeksi SQL (meskipun Anda menggunakan ORM)
- Kirim payload XSS di bidang string
- Kirim tipe data yang tidak cocok (string di mana angka diharapkan, dll.)
Saya tahu apa yang Anda pikirkan: "Sarah, itu gila. Tidak ada yang punya waktu untuk semua itu." Tapi—saya telah mengotomatiskan seluruh daftar periksa ini. Saya memiliki generator data uji yang menghasilkan semua variasi ini secara otomatis. Pengaturan awal memakan waktu sekitar dua minggu untuk dibangun, tetapi sekarang saya dapat menjalankan seluruh rangkaian ini terhadap endpoint baru dalam waktu sekitar 15 menit.
Hasilnya nyata. Bulan lalu, daftar periksa ini menangkap satu endpoint yang akan membuat seluruh server API mengalami crash saat Anda mengirimkan string yang lebih panjang dari 65.535 karakter. Pengembang mengasumsikan bahwa basis data akan menangani validasi panjang, tetapi basis data dikonfigurasi untuk memotong dengan diam, dan kode aplikasi mencoba mencatat string lengkap ke buffer berukuran tetap. Boom—segmentation fault, server down.
Untuk bidang tanggal dan waktu, saya memiliki sub-daftar periksa khusus karena ini sangat buruk:
- Kirim tanggal dalam berbagai format (ISO 8601, MM/DD/YYYY, DD/MM/YYYY, dll.)
- Kirim tanggal yang tidak valid (30 Februari, bulan 13, hari 32)
- Kirim tanggal yang jauh di masa lalu (tahun 1900, tahun 1)
- Kirim tanggal yang jauh di masa depan (tahun 2100, tahun 9999)
- Kirim tanggal dengan offset zona waktu yang berbeda
- Kirim tanggal selama transisi waktu musim panas
- Kirim timestamp dengan milidetik, mikrodetik, nanodetik
Yang satu tentang waktu musim panas ini telah menggigit saya dua kali. Dua kali! Anda mungkin pikir saya akan belajar, tetapi ini adalah kasus tepi yang aneh sehingga mudah untuk dilupakan. Saya sekarang memiliki tes khusus yang menjalankan transaksi pada pukul 2 pagi pada hari jam berubah, karena itulah saat hal aneh terjadi.
Validasi Respons: Percaya, Tapi Verifikasi
Kebanyakan penguji sangat fokus pada permintaan dan hampir tidak memperhatikan respons. Itu terbalik. Respons API Anda adalah kontraknya dengan dunia. Jika mereka tidak konsisten, tidak lengkap, atau salah, Anda telah memutuskan kontrak itu.
| Kategori Uji | Titik Kegagalan Umum | Respons yang Diharapkan | Apa yang Sebenarnya Terjadi |
|---|---|---|---|
| Tidak Ada Token Otentikasi | Penanganan kesalahan yang hilang | 401 Tidak Diizinkan | 500 Kesalahan Server Internal atau data yang terungkap |
| Token Kedaluwarsa | Logika validasi token | 401 Tidak Diizinkan | Kesalahan 500 atau kegagalan diam |
| Token yang Tidak Terformat dengan Benar | Validasi input | 401 Tidak Diizinkan | Kecelakaan aplikasi atau eksposur stack trace |
| Token Valid, Izin Salah | Pemeriksaan otorisasi | 403 Dilarang | 200 OK dengan akses data yang tidak sah |
| Format Tanggal Tidak Valid | Pemurnian input | 400 Permintaan Buruk | Kegagalan cascade transaksi |
Daftar periksa validasi respons saya mencakup:
- Verifikasi bahwa kode status respons cocok dengan perilaku yang didokumentasikan
- Verifikasi bahwa header jenis konten respons benar
- Verifikasi bahwa struktur badan respons cocok dengan skema
- Verifikasi bahwa semua bidang yang didokumentasikan ada
- Verifikasi bahwa tidak ada bidang yang tidak didokumentasikan yang ada (ini penting untuk versi API)
- Verifikasi bahwa tipe data bidang cocok dengan dokumentasi
- Verifikasi bahwa nilai bidang berada dalam rentang yang didokumentasikan
- Verifikasi bahwa timestamp berada di zona waktu yang benar
- Verifikasi bahwa metadata paginasi benar dan konsisten
- Verifikasi bahwa respons kesalahan menyertakan pesan kesalahan yang bermanfaat
- Verifikasi bahwa respons kesalahan menyertakan kode kesalahan untuk penanganan programatik
Poin kedua terakhir tentang pesan kesalahan sangat penting. Saya telah melihat API yang mengembalikan "Kesalahan" sebagai seluruh pesan kesalahan. Itu tidak berguna. Pesan kesalahan yang baik memberitahu Anda apa yang salah, mengapa itu salah, dan idealnya apa yang dapat Anda lakukan untuk memperbaikinya. Bandingkan dua respons kesalahan ini:
Buruk: {"error": "Permintaan tidak valid"}
Baik: {"error": "Permintaan tidak valid", "message": "Bidang 'email' diperlukan tetapi tidak disediakan", "code": "MISSING_REQUIRED_FIELD", "field": "email"}
Yang kedua terakhir...