Klinik A dan Klinik B berbagi satu basis kode, dua subdomain, dan campuran pengunjung dari kantor serta VPN. Tim jaringan cenderung mengonfigurasi kedua pintu masuk secara terpisah, dan itu wajar, asalkan aplikasi tidak melakukannya. Pemeriksaan di bawah ini harus ada di aplikasi dan berperilaku sama, tidak peduli pintu mana yang dipakai permintaan.

Pertama: nama host hanya menamai penyewa

Cocokkan nama host yang diminta dengan pemetaan yang dipelihara administrator, dan tolak apa pun yang tidak dikenal. Gunakan nilai host tervalidasi dari framework, bukan header mentah, agar Host buatan tidak dapat menyuntikkan kunci pencarian. Kecocokan yang berhasil memberi tahu kode konfigurasi penyewa dan merek mana yang harus dimuat. Ini tidak mengatakan apa pun tentang apakah pemanggil boleh melihat data penyewa tersebut. Simpan pertanyaan kedua itu di fungsi terpisah dengan masukan terpisah.

Fungsi bantu bersama yang mengembalikan konteks dan izin sekaligus dari satu pencarian nama host adalah awal dari bug tersebut.

Kedua: keanggotaan berasal dari sesi

Cari keanggotaan aktif pengguna yang terautentikasi dan bandingkan dengan penyewa dari pemeriksaan pertama. Pengguna yang menjadi anggota kedua klinik boleh berpindah, tetapi perpindahan itu harus berupa tindakan eksplisit yang dicatat dalam konteks permintaan, bukan kesimpulan dari URL. Pengguna yang menjadi anggota satu klinik dan meminta klinik lain ditolak, termasuk untuk unduhan dan panggilan API.

Uji kasus negatif dengan mengubah pengenal catatan dan parameter penyewa. Jika salah satu perubahan mengembalikan data, cakupan dibaca dari permintaan, bukan dari keanggotaan terverifikasi.

Cakupan cookie dan masuk tunggal menentukan di mana akun dapat disajikan. Keduanya tidak menentukan apa yang boleh dibaca akun tersebut.

Ketiga: jaringan tidak membuktikan apa pun tentang orangnya

Gerbang VPN mengautentikasi terowongan, dan daftar izin publik mengautentikasi rentang alamat. Keduanya tidak mengidentifikasi orang. NAT menyatukan banyak pengguna ke dalam satu alamat sumber, dan rentang kantor melakukan hal yang sama bagi semua orang di gedung. Perlakukan keduanya sebagai fakta transportasi dan simpan otorisasi di aplikasi, atau dalam integrasi yang menyatakan identitas secara eksplisit dan ditinjau sebagai demikian.

DNS adalah fakta transportasi ketiga. Jawaban privat memerlukan rute privat, dan frontend publik memerlukan jalur asal yang didukung. Tidak satu pun dari keduanya membawa izin.

Satu kalimat untuk ditempel di dinding: jaringan menentukan bagaimana permintaan tiba, dan aplikasi menentukan apa yang boleh dibacanya.

Keempat: jalankan matriks di kedua pintu masuk

Gunakan akun terkontrol untuk menguji A di A, B di B, A di B, nama host tak dikenal, dan akun terautentikasi tanpa keanggotaan. Yang keempat dan kelima harus gagal tertutup dan tidak boleh jatuh ke penyewa default. Jalankan matriks yang sama melalui pintu masuk VPN juga, dengan satu toples sesi per akun:

curl -s -o /dev/null -w '%{http_code}' -b jar.txt https://clinic-b.example.com/records/42
curl -s -o /dev/null -w '%{http_code}' -b jar.txt https://clinic-a.example.com/records/42

Lalu ubah satu entri daftar izin dan jalankan ulang. Hasil yang bergeser berarti kontrol jaringan sedang membuat keputusan otorisasi.

Ulangi matriks setelah setiap perubahan frontend, karena jalur kode kedua yang melewati pemeriksaan adalah cara paling umum batas ini terkikis. Hasil yang diharapkan membosankan: setiap pintu masuk menghasilkan jawaban yang sama.

Artikel terkait