Haruskah MVC / REST mengembalikan 403 atau 404 untuk sumber daya milik pengguna lain?

33

Ketika bekerja dengan situs berbasis sumber daya (seperti aplikasi MVC atau layanan REST), kami memiliki dua opsi utama ketika klien mencoba ke GETsumber daya yang mereka tidak memiliki akses ke:

  • 403 , yang mengatakan bahwa klien tidak sah ; atau
  • 404 , yang mengatakan bahwa sumber daya itu tidak ada (atau tidak dapat ditemukan).

Kebijaksanaan umum dan praktik umum tampaknya merespons dengan kebenaran - yaitu 403. Tetapi saya bertanya-tanya apakah ini sebenarnya hal yang benar untuk dilakukan.

Sistem login yang aman tidak pernah memberi tahu Anda alasan kegagalan login. Artinya, sejauh menyangkut klien, tidak ada perbedaan yang dapat terdeteksi antara nama pengguna yang tidak ada dan kata sandi yang salah. Tujuannya adalah untuk tidak membuat ID pengguna - atau lebih buruk, alamat email - dapat ditemukan.

Dari sudut pandang privasi , tampaknya jauh lebih aman untuk mengembalikan 404. Saya teringat akan insiden di mana seseorang dilaporkan menemukan pemenang dari reality show (Survivor, saya pikir) dengan melihat sumber daya yang tidak ada pada situs vs. mana yang melakukannya. Saya khawatir tentang 403 yang berpotensi memberikan informasi sensitif seperti nomor seri atau nomor akun.

Apakah ada alasan kuat untuk tidak mengembalikan 404? Bisakah kebijakan 404 memiliki efek samping negatif di tempat lain? Jika tidak, mengapa praktik itu tidak lebih umum?

Aaronaught
sumber
1
Alasan kuat untuk tidak mengembalikan 404: Jika layanan sedang down atau ada bug / kesalahan dalam otentikasi maka Anda akan mendapatkan 404, tetapi pelanggan / pengguna / penguji / pengembang / pendukung yang mencoba mendiagnosis masalah mungkin tidak tahu apa yang salah dari pesan kesalahan.
Steven Evers
@Snorfus: Itu poin yang bagus - saya akan menjawabnya. Meskipun Josh sudah menambahkan tandingan yang baik ...
Aaronaught
Aspek lain yang perlu diingat adalah ini: bagaimana perawatan 404 di hilir? Apakah ada CDN atau semacam caching? Jika Anda pernah ingin bisa men-cache itu, maka Anda mungkin tidak ingin "404 pengguna" Anda tidak memiliki izin untuk di-cache.
pc1oad1etter

Jawaban:

15

Ada kesalahpahaman umum (dan penyalahgunaan) yang terkait 403 Forbidden: itu tidak seharusnya memberikan apa pun tentang apa yang dipikirkan server tentang permintaan tersebut. Ini secara khusus dirancang untuk mengatakan,

Saya mendapatkan apa yang Anda minta, tetapi saya tidak akan menangani permintaan itu, apa pun yang Anda coba. Jadi berhentilah mencoba.

UA atau klien mana pun harus menafsirkan bahwa itu berarti bahwa permintaan itu tidak akan pernah berfungsi, dan merespons dengan tepat.

Ini memiliki implikasi untuk klien yang menangani permintaan atas nama pengguna: jika pengguna tidak masuk, atau salah ketik, klien yang menangani permintaan tersebut harus menjawab, "Maaf, tapi saya tidak bisa melakukan apa-apa" setelah pertama kali itu mendapatkan 403dan berhenti menangani permintaan di masa depan. Jelas, jika Anda ingin pengguna masih dapat meminta akses ke informasi pribadi mereka setelah kegagalan, ini adalah perilaku yang bermusuhan dengan pengguna.

403berbeda dengan 401 Authorization Required, yang tidak memberikan bahwa server akan menangani permintaan selama Anda lulus kredensial yang benar. Ini biasanya yang dipikirkan orang ketika mereka mendengar 403.

Ini juga berbeda dengan 404 Page Not Foundyang, seperti yang ditunjukkan orang lain, dirancang tidak hanya untuk mengatakan "Saya tidak dapat menemukan halaman itu" tetapi untuk menyarankan kepada klien bahwa server tidak membuat klaim keberhasilan atau kegagalan untuk permintaan di masa depan.

Dengan 401dan 404, server tidak mengatakan apa pun kepada klien atau UA tentang bagaimana mereka harus melanjutkan: mereka dapat terus berusaha dengan harapan mendapatkan respons yang berbeda.

Jadi 404adalah cara yang tepat untuk menangani halaman yang tidak ingin Anda tunjukkan kepada semua orang, tetapi tidak ingin memberikan apa pun tentang mengapa Anda tidak akan menampilkannya dalam situasi tertentu.

Tentu saja, ini mengasumsikan klien membuat permintaan peduli untuk kelemahan RFC kecil. Klien yang cukup jahat tidak akan peduli tentang kode status yang dikembalikan kecuali secara insidentil. Orang akan tahu itu adalah halaman pengguna tersembunyi (atau halaman pengguna potensial yang tersembunyi) dengan membandingkannya dengan halaman pengguna lain yang dikenal.

Yaitu, katakanlah pawang Anda users/*. Jika saya tahu users/foo, users/bardan users/baazpekerjaan, server mengembalikan 401, 403atau 404untuk users/quuxtidak berarti aku tidak akan mencobanya, terutama jika saya punya alasan untuk percaya ada adalah sebuah quuxpengguna. Skenario contoh standar adalah Facebook: profil saya pribadi, tetapi komentar saya tentang profil publik tidak. Klien jahat tahu saya ada meskipun Anda kembali 404ke halaman profil saya.

Jadi kode status bukan untuk kasus penggunaan berbahaya, itu untuk klien yang bermain sesuai aturan. Dan untuk klien - klien itu, suatu 401atau 404permintaan adalah yang paling tepat.


sumber
4
Poin bagus sekitar 401 vs 403. Namun, saya tidak setuju dengan finalitas pernyataan Anda pada 404. Tentu, dalam contoh Facebook, Anda sudah tahu yang quuxada. Tetapi tidak akan selalu ada bukti eksternal, terutama di situs non-sosial di mana data klien benar - benar pribadi . Sebuah usil atau bermusuhan pengguna akhirnya mungkin bisa menyimpulkan bahwa Anda berbaring, tetapi belum tentu yang sumber daya yang Anda berbohong tentang . Saya pikir poin penting di sini adalah benar-benar, jangan repot-repot untuk sumber daya 404 kecuali tidak ada metode penemuan lain yang tersedia.
Aaronaught
@Aonaonaught Masalahnya adalah, Anda harus benar-benar yakin seseorang tidak dapat mengetahui apa yang ditipu oleh server, atau bahwa tidak ada metode penemuan yang belum pernah Anda lakukan. Orang yang cukup pintar akan mencari tahu, dan pada saat itu, kode status tidak ada artinya.
1
Saya masih belum jelas tentang bagaimana orang yang cukup pintar bisa mengetahuinya jika tidak ada berbagi data antara profil pengguna. Saya mengerti bahwa seseorang yang bertekad akhirnya akan menyadari "oh, 404 sebenarnya berarti mungkin ada, tapi saya tidak bisa mengaksesnya" - tetapi dengan asumsi bahwa server mengembalikan kesalahan yang sama untuk sumber daya yang benar - benar tidak ada, bagaimana mungkin katakan perbedaan antara sumber daya yang tidak ada dan yang istimewa?
Aaronaught
@Aonaona satu-satunya hal yang perlu diketahui seseorang adalah URL ke profil harus ada. Anda mungkin hanya menggunakan ID profil dan menambahkannya dengan cara semu (jadi orang dengan ID profil 3333 tidak berarti ada orang dengan ID profil 3332), tetapi orang yang berketentuan harus dapat memperkirakannya dengan memberikan beberapa ukuran sampel ID yang valid. Kegagalan itu, dan bahkan diberikan sistem yang sangat keras yang tidak membocorkan informasi tentang cara menghasilkan URL untuk halaman profil, selalu ada rekayasa sosial.
8

Menurut RFC2616

10.4.4 403 Dilarang

Server mengerti permintaan itu, tetapi menolak untuk memenuhinya. Otorisasi tidak akan membantu dan permintaan TIDAK HARUS diulang. Jika metode permintaan itu bukan KEPALA dan server ingin mengumumkan kepada publik mengapa permintaan itu belum dipenuhi, itu HARUS menggambarkan alasan penolakan dalam entitas. Jika server tidak ingin membuat informasi ini tersedia untuk klien, kode status 404 (Tidak Ditemukan) dapat digunakan sebagai gantinya.

juga perhatikan bahwa ketika mengakses sumber daya Terlarang, otorisasi tidak akan membantu .

Lie Ryan
sumber
Saya menyadari RFC, meskipun sedikit mirip dengan kenyataan. Hampir tidak ada server yang pernah menjelaskan alasan 403 di luar kalimat pertama ("Server memahami permintaan, tetapi menolak untuk memenuhinya.") Dan sebagian besar kerangka kerja MVC bahkan memiliki sesuatu yang mirip dengan HttpUnauthorizedResultyang dimaksudkan untuk digunakan sebagai sumber daya istimewa. . Saya juga menyadari (jelas) bahwa 404 dapat digunakan sebagai gantinya; pertanyaan saya adalah apakah harus digunakan atau tidak , dan apa yang harus dipertimbangkan ketika membuat keputusan itu.
Aaronaught
@Aaronaught: RFC tidak hanya memungkinkan Anda untuk menggunakan 404, itu merekomendasikan bahwa 404 dilemparkan ketika Anda tidak ingin mengakui apa pun.
Lie Ryan
3
Tidak apa-apa, tetapi kapan saya tidak mengakui apa pun? Atau lebih tepatnya, kapan aku harus ? Itu benar-benar inti dari pertanyaan.
Aaronaught
5

Seharusnya kamu? Ya .

Anda mengatakannya sendiri, mengkhianati sesedikit mungkin. Jika saya menyerang sistem dan melihat server merespons dengan 403 kode saya akan fokus pada mereka, daripada pindah. Lebih baik sebuah pintu menyatakan itu tidak ada kemudian mengumumkannya untuk dilarang.

Kelemahan dari menggunakan 404 permintaan adalah bahwa secara eksternal akan muncul seolah-olah halaman tidak ada, dan ini bisa memiliki konflik bila dibandingkan dengan halaman yang seharusnya ada tetapi malah hilang. Jika Anda tidak khawatir tentang perayap web (sistem terotentikasi harus sepenuhnya ditolak), maka Anda harus benar-benar melakukannya. Setiap API yang saya tangani memiliki akses tidak sah dengan cara yang sama persis, dan begitu pula StackOverflow . Tidak bisa melihat halaman itu? Saya yakinkan Anda itu memang ada, meskipun ia mengaku tidak.

Anda harus mengakui permintaan ketika sumber daya diketahui ada dan akses ditolak. Gagal masuk seharusnya tidak menghasilkan pesan 404. Anda seharusnya tidak mengakui permintaan ketika keberadaan sumber daya itu sendiri harus dilindungi. Akses ke ranah ada di publik, tetapi grup keamanan atau peran di dalamnya tidak.


Alasan kuat untuk tidak mengembalikan 404: Jika layanan sedang down atau ada bug / kesalahan dalam otentikasi maka Anda akan mendapatkan 404, tetapi pelanggan / pengguna / penguji / pengembang / pendukung yang mencoba mendiagnosis masalah mungkin tidak tahu apa yang salah dari pesan kesalahan

Pengembang harus memiliki akses ke log, yang akan mengindikasikan upaya untuk mengakses sumber daya yang dilindungi. Pelanggan / Pengguna / Penguji akan menghasilkan umpan balik yang pada akhirnya akan mengenai pengembang.

Keamanan dengan ketidakjelasan ... sungguh?

Ini bukan keamanan karena ketidakjelasan. Anda menggunakan ketidakjelasan selain langkah-langkah keamanan yang tepat.

Sebaliknya, permintaan yang valid untuk mendapatkan "404" hanya menambah kompleksitas dan ketidakjelasan di tempat yang tidak perlu

Mereka bukan permintaan yang valid, itu adalah permintaan yang tidak sah . Anda mengubah sebagian kecil (mengembalikan 404 bukannya 403) untuk mendapatkan keuntungan besar pada calon penyerang.

Josh K.
sumber
Keamanan dengan ketidakjelasan ... sungguh? Jika seseorang mencoba menyodok layanan Anda dengan niat jahat, mereka sudah tahu itu ada di sana. Sebaliknya, permintaan yang valid untuk mendapatkan "404" hanya menambah kompleksitas dan ketidakjelasan di tempat yang tidak perlu.
Steven Evers
4
@Snorfus: Ada perbedaan tipis yang dibuat di sini antara keamanan dan privasi . Privasi, hampir secara definisi, "oleh ketidakjelasan". Ini sangat penting dalam konteks sistem berbasis sumber daya , karena keberadaan atau tidak adanya sumber daya berpotensi informasi penting. Mungkin ada argumen keamanan juga, meskipun saya kurang peduli dengan itu. Saya akan ingin mendengar lebih banyak tentang kompleksitas menambahkan ini; dapatkah Anda menjelaskan lebih lanjut dari komentar awal Anda? (Mungkin dalam jawaban yang lebih komprehensif? Apakah Anda pernah digigit 404-an pada 403-an?)
Aaronaught
2
@Snorfus: Saya juga ingin menambahkan, sebagai renungan, bahwa pertahanan secara mendalam tidak sama dengan keamanan oleh ketidakjelasan . Yang terakhir menyiratkan bahwa tidak ada lain sarana perlindungan. Tetapi menambahkan ketidakjelasan ke sistem yang sudah aman sering kali bisa menjadi hal yang baik - asalkan tidak menyebabkan masalah lain di jalan. Dalam hal ini, itu adalah mengingat bahwa sistem sudah diamankan, karena 404 sedang dipancarkan oleh kode otorisasi.
Aaronaught
@Aaronaught: Saya akan memposting jawaban yang lebih mendalam, tetapi tentang masalah ini: jika sumber daya bersifat pribadi, lalu apa alasan di balik mengeksposnya secara publik?
Steven Evers
@Snorfus: Sumber daya bersifat pribadi untuk klien - atau mungkin untuk grup - tidak untuk seluruh dunia.
Aaronaught
0

Itu benar-benar tergantung pada informasi yang diberikan oleh kode status 403. Jika Anda memiliki titik akhir API merespons GET /myresource/{id}dengan 404 ketika sumber daya tidak ada, maka kode status dikembalikan oleh titik akhir ketika sumber daya ada tetapi tidak diotorisasi untuk pengguna saat ini harus bergantung pada prediktabilitas idparameter, dan jumlah informasi yang dikandungnya dengan sendirinya.

  • Jika idbidang pribadi seperti alamat email atau nomor rekening bank, mungkin harus selalu disembunyikan di belakang angka 404. Dalam kasus alamat email, bidang tersebut dapat mencegah bot spam dari menyusun daftar alamat email yang valid yang terdaftar di situs web Anda.
  • Jika idadalah nama pengguna publik, jangan repot-repot, ada cara lain untuk mendapatkan akses ke informasi ini (seperti, hanya dengan menjelajahi halaman forum situs web Anda).
  • Jika idbersifat buram, tetapi pengidentifikasi yang dapat diprediksi (mis. Bilangan bulat yang bertambah secara otomatis), Anda tidak memberikan informasi apa pun kepada penyerang yang tidak dapat ia peroleh dengan cara lain. Jadi menurut saya aman untuk mengembalikan kode status 403.
  • Jika idpengidentifikasi buram dan tidak dapat diprediksi (seperti GUID acak), pertanyaannya lebih halus. Saya pribadi berpikir tidak ada masalah dalam mengembalikan kode status 403. Informasi ini hanya dapat dieksploitasi jika ada titik akhir cacat lain di API Anda menggunakan ID ini, tetapi cacat sebenarnya adalah titik akhir Anda yang lain.

Anda mungkin menganggap lebih baik aman daripada menyesal dalam hal apa pun dan menyembunyikan informasi apa pun konteksnya, tetapi Anda sebenarnya tidak bisa mengandalkan jenis perilaku ini untuk menyediakan segala bentuk keamanan . Di sisi lain, ini dapat memberikan kerahasiaan (atau privasi, seperti yang dikatakan orang lain).

Mekanisme keamanan seharusnya tidak hanya menjadi gundukan cepat bagi penyerang, jika tidak, itu hanya sia-sia. Dalam hal ini, bahkan mungkin mencegah Anda menggunakan fitur lain dengan benar (crawler, Aplikasi Web Firewall mencari jumlah abnormal 403 kode status untuk memblokir pengguna ...).

Maxime Rossini
sumber