Django-tastypie: Membutuhkan default yang jauh lebih aman: `DjangoAuthorization` seharusnya tidak membolehkan akses` membaca` ke semua objek model

Dibuat pada 6 Jan 2016  ·  10Komentar  ·  Sumber: django-tastypie/django-tastypie

Melihat tastypie/authorization.py (sekitar seperti 133 - cabang master pada 1/4/2016), defaultnya, baik read_list dan read_details memotong user.has_perm() cek, yang cukup tidak aman dan merupakan default yang buruk.

Standar Admin Django tidak konvensional. Jadi, saya bisa melihat bagaimana itu disalahartikan.

https://docs.djangoproject.com/es/1.9/topics/auth/default/#permissions -and-authorization

The Django admin site uses permissions as follows:
*   ... 
* Access to view the change list, view the “change” form and change an object is limited to users with the “change” permission for that type of object.

Pada dasarnya, "change_xyz" adalah kode izin untuk "read" dan "update". Saya pikir default yang lebih baik adalah mengikuti Admin Django:

diff --git a/tastypie/authorization.py b/tastypie/authorization.py
index 1d6f5aa..44b2d56 100644
--- a/tastypie/authorization.py
+++ b/tastypie/authorization.py
@@ -151,22 +151,14 @@ class DjangoAuthorization(Authorization):
         return model_klass

     def read_list(self, object_list, bundle):
-        klass = self.base_checks(bundle.request, object_list.model)
-
-        if klass is False:
-            return []
+        # By default, follows `ModelAdmin` "convention" to use `app.change_model`
+        # `django.contrib.auth.models.Permission` for both viewing and updating.
+        # https://docs.djangoproject.com/es/1.9/topics/auth/default/#permissions-and-authorization

-        # GET-style methods are always allowed.
-        return object_list
+        return self.update_list(object_list, bundle)

     def read_detail(self, object_list, bundle):
-        klass = self.base_checks(bundle.request, bundle.obj.__class__)
-
-        if klass is False:
-            raise Unauthorized("You are not allowed to access that resource.")
-
-        # GET-style methods are always allowed.
-        return True
+        return self.update_detail(object_list, bundle)

bug immediate

Komentar yang paling membantu

Saat Anda membuat perubahan yang mengganggu produksi, dapatkah Anda setidaknya mencerminkannya dalam pembuatan versi?
x.y.z versi Tastypie terlihat sangat mirip dengan apa yang diharapkan kebanyakan orang , yang biasanya adalah:

Diberikan nomor versi MAJOR.MINOR.PATCH, tambahkan:
..
Versi PATCH saat Anda melakukan perbaikan bug yang kompatibel dengan versi sebelumnya.

Saya hanya menghabiskan satu jam yang sangat tidak nyaman untuk menelusuri ini selama penerapan produksi baru.

Semua 10 komentar

Saya menghargai ini sudah digabungkan tetapi saya masih mempermasalahkannya. Sebelum membuka permintaan baru, inilah perhatian saya:

Sayangnya perubahan ini merusak kode yang ada dan karenanya tidak kompatibel ke belakang (sebelumnya semua permintaan GET akan melewati DjangoAuthorization). Untuk memperbaiki kode seseorang, satu-satunya pilihan adalah memberikan izin 'perubahan' kepada semua pengguna (buruk), atau subkelas DjangoAuthorization untuk implementasi kustom dari aksi baca (berpotensi banyak pekerjaan). Apakah ini dimaksudkan?

Saya menghargai alasan di balik ini dalam konteks admin django, tapi saya ragu pengaturan 'baca' sebagai setara dengan 'perubahan' dalam konteks API adalah asumsi default yang masuk akal karena ini bukan perilaku yang diharapkan. Lagi pula, jika GET adalah metode yang diperbolehkan bersama dengan DjangoAuthorization, mengapa menolak akses berdasarkan fakta bahwa pengguna tidak memiliki izin change ?

Saya mengusulkan dia mengikuti implementasi alternatif:

_untuk read_detail_

  • jika model memiliki izin view , periksa (= peningkatan bagi mereka yang membutuhkannya)
  • jika tidak ada izin view , selalu izinkan (= kompatibel dengan versi sebelumnya)

_untuk read_list_

  • jika model memiliki izin list , periksa (= peningkatan bagi mereka yang membutuhkannya)
  • jika tidak ada izin list , selalu izinkan (= kompatibel dengan versi sebelumnya)

Dengan cara ini tastypie menambahkan default yang kompatibel dengan default izin Django sambil memberikan jalur yang mudah untuk diperbaiki dengan menambahkan izin tampilan dan daftar bagi mereka yang membutuhkannya, singkatnya menulis implementasi kustom dari DjangoAuthorization.

Setidaknya harus ada cara untuk menentukan izin default:

DjangoAuthorization(read_permission='view', # applies to both list, detail if not spec'd
                    read_list_permission='view', # list only
                    read_detail_permission='view') # detail only
# while we're at it, why not add the other permissions too
DjangoAuthorization(change_permission='change',
                    delete_permission='delete',
                    add_permission='add', 
                    # ... add options as per above for each
                    # <action>_<level> permission where 
                    # action is `change,delete,add,read`,  level is `list,detail`)

@SeanHayes akan menjadi orang yang memutuskan.

Hanya pendapat saya di sini, saya pikir itu adalah masalah keamanan untuk memungkinkan membaca secara default. Saya benar-benar tidak mengharapkannya, sampai saya sangat dekat dengan produksi. Saya pikir melanggar backward-compat diperlukan dalam konteks ini.

Sepertinya saran Anda memerlukan perubahan params pass ke DjangoAuthorization ke kode yang ada, dalam hal ini saya akan berpikir lebih jelas untuk memanggil kelas dengan sesuatu yang lain.

Pertimbangkan, read_permission='view' case, inilah yang mungkin Anda butuhkan. Saya tidak melihat mengapa itu kurang optimal

class ModifiedDjangoAuthorization(DjangoAuthorization):
    READ_PERM_CODE = 'view'

Jika Anda ingin mengubah yang lain, cukup ganti metode. Perubahan tersebut sebenarnya dirancang untuk membuatnya sangat mudah dilakukan.

class ModifiedDjangoAuthorization(DjangoAuthorization):
    def delete_list(self, object_list, bundle):
        return self.perm_list_checks(bundle.request, 'del', object_list)

    def delete_detail(self, object_list, bundle):
        return self.perm_obj_checks(bundle.request, 'del', bundle.obj)

Perubahan itu mempertimbangkan modifikasi dan membuatnya mudah. Saya tidak perlu berpikir itu harus dilakukan sebagai init params.

Saya pikir itu adalah masalah keamanan untuk mengizinkan pembacaan secara default.

Saya tidak mempertanyakan maksud dari masalah aslinya. Hanya menunjukkan bahwa penerapan sebagai gabungan melanggar kode & asumsi orang yang ada tanpa mengatakannya dan tanpa opsi yang efisien untuk mengembalikan.

Sepertinya saran Anda memerlukan perubahan parameter pass ke DjangoAuthorization ke kode Anda yang ada,

Jika Anda melihat solusi yang saya usulkan lagi, yang saya anjurkan adalah memberi orang opsi dengan default yang kompatibel dengan aman dan mundur. Tidak ada perubahan yang diperlukan dalam kode pengguna dalam kasus ini.

Saya pikir melanggar backward-compat diperlukan dalam konteks ini.

Saya tidak setuju. Perubahan yang saat ini digabungkan tidak hanya merusak kompatibilitas ke belakang tetapi juga memperkenalkan masalah keamanan potensial yang jauh lebih besar dengan cara yang jelas (tersirat oleh implementasi saat ini) adalah dengan menetapkan izin perubahan ke semua pengguna yang seharusnya diizinkan GET.

Terus terang, saya gagal untuk melihat bagaimana izin change untuk tindakan membaca meningkatkan keamanan karena pada saat yang sama izin ini juga memungkinkan PUT. Mencampur izin untuk tindakan yang berbeda sepertinya bukan pilihan yang baik.

Sayangnya, usulan ModifiedDjangoAuthorization tidak akan berhasil kecuali jika Anda benar-benar menambahkan izin view ke model, sehingga sekali lagi melanggar kompatibilitas ke belakang. Setidaknya itu membutuhkan perubahan kode - jadi kami merusak kompatibilitas mundur _ dan_ memaksa pengguna untuk mengerjakan ulang basis kode mereka.

Tentu saja mengesampingkan selalu merupakan opsi untuk mencapai persyaratan spesifik seseorang, namun menurut saya ide umum di tastypie adalah menyediakan default yang masuk akal & aman yang tidak memerlukan penambahan kode khusus ...

Singkatnya, saya pikir perubahan ini harus dikembalikan untuk implementasi yang lebih baik.

Izin change datang dari Django itu sendiri. Ini adalah default Django, ini adalah bagaimana aplikasi Django Admin diatur. Opsi view tidak. Saya pribadi menamai milik saya sebagai read .

Tidak yakin apa yang Anda maksud dengan memeriksa model . Jika Anda bermaksud memeriksa _meta, mungkin itu tidak lengkap. Jika Anda bermaksud memukul db, menurut saya tidak perlu mahal.

Menurut preferensi saya, apa yang Anda usulkan tampaknya berada di sisi "terlalu ajaib" untuk otorisasi default. Hanya memiliki default yang aman, mudah diganti, tampaknya sudah cukup. Tapi, itu baru pendapat saya.

Perubahan tersebut didokumentasikan di sini: https://github.com/django-tastypie/django-tastypie/blob/master/docs/release_notes/v0.13.2.rst

Terus terang, saya gagal melihat bagaimana izin perubahan untuk tindakan baca meningkatkan keamanan karena pada saat yang sama izin ini juga mengizinkan PUT. Mencampur izin untuk tindakan yang berbeda sepertinya bukan pilihan yang baik.

Kita tahu bahwa jika pengguna dapat mengubah sesuatu, maka mereka dapat membacanya, begitulah cara admin Django melakukan sesuatu.

Versi ini lebih aman, karena memaksa pengembang untuk memikirkan tentang apa yang mereka lakukan. Jika alih-alih menemukan izin "baca" mereka sendiri, pengembang memilih untuk dengan sengaja memberikan izin "perubahan" kepada semua orang ketika mereka seharusnya hanya memiliki izin "baca", itu masalah mereka; Saya tidak bisa menghentikan developer lain untuk dengan sengaja melakukan hal-hal bodoh, saya di sini untuk menghentikan Tastypie melakukan hal-hal bodoh. Inti dari perubahan ini adalah untuk mencegah izin baca global pada sumber apapun yang menggunakan DjangoAuthorization, yang mungkin tidak diharapkan oleh pengembang; perilaku baru sejalan dengan pengalaman pengembang di admin Django.

Jika Anda menginginkan perilaku lama:

  1. Jangan tingkatkan ke 0.13.2.
  2. Atau ganti metode read_list and read_detail`.

Jika menurut Anda dokumentasinya bisa diperbaiki, silakan kirimkan PR.

menghargai tanggapan Anda. terima kasih untuk tautan ke dokumen, cukup adil, saya buruk karena melewatkannya (harap perhatikan masalah ini ditugaskan ke v0.13.4 sedangkan dokumen ada di v0.13.2).

Izinkan saya membuat beberapa komentar terakhir dari pov saya:

Kita tahu bahwa jika pengguna dapat mengubah sesuatu, maka mereka dapat membacanya, begitulah cara admin Django melakukan sesuatu.

Admin Django menggunakan izin change karena antarmuka admin _is_ tentang _changing_ objek. Masuk akal di sana. Permintaan GET pada REST API menurut definisi adalah tentang _membaca / melihat_. Saya akan berpikir bahwa kebanyakan pengembang tidak mengharapkan DjangoAuthorization untuk menolak membaca berdasarkan izin yang hilang untuk berubah.

Versi ini lebih aman, karena memaksa pengembang untuk memikirkan tentang apa yang mereka lakukan.

Salah satu fitur tastypie yang diiklankan adalah menyediakan _reasonable defaults_. Bukankah cukup masuk akal untuk mengasumsikan bahwa metode GET (menurut definisi: read) dan PUT (perubahan) API, sebagai operasi yang berbeda dalam semua maksud dan tujuan, juga memerlukan izin yang berbeda?

Saya akan dengan senang hati menyumbangkan PR sesuai dengan apa yang saya tulis jika menurut Anda ini adalah tambahan yang berharga.

Izin perubahan datang dari Django sendiri. (...) Tampilan opsi tidak.

ada PR yang tertunda di Django untuk menambahkan view permission itulah mengapa saya menggunakan view.

Kami tidak akan mengizinkan operasi baca publik / global secara default. Itu final. Dan kami tidak akan mencoba dan menebak bagaimana pengembang mengatur izin mereka ketika saat ini tidak ada cara standar untuk melakukannya. Kami bahkan tidak yakin apakah akan menyebutnya "baca" atau "tampilan", dan saya tidak ingin sekelompok orang yang datang ke sini mengatakan "Saya melakukannya dengan cara ini" atau "terbitan Django baru menyebutnya sesuatu yang lain" .

Jika dan ketika Django mendukung izin baca / lihat di luar kotak kita akan beralih ke itu. Untuk saat ini pengembang hanya perlu menulis beberapa kode khusus untuk menangani cara khusus mereka menangani izin.

Saya tahu masalah ini sudah ditutup tetapi saya hanya ingin berpadu dan mengatakan bahwa perubahan ini pada dasarnya memblokir saya dari memigrasi proyek yang ada ke 0.13.x.

@miraculixx Saya pikir Anda sepenuhnya benar sehubungan dengan fakta bahwa memerlukan izin perubahan hanya untuk melihat data agak gila. Saya kira kita dapat menyalahkan Django untuk entah bagaimana, masih, tidak memiliki konsep izin tampilan (Yang membuat saya tidak bisa melihat ke tingkat yang lain, saya pikir itu gila bahwa proyek yang menyertakan komponen admin CRUD sama sekali tidak memiliki izin untuk bagian BACA dari CRUD).

Saat Anda membuat perubahan yang mengganggu produksi, dapatkah Anda setidaknya mencerminkannya dalam pembuatan versi?
x.y.z versi Tastypie terlihat sangat mirip dengan apa yang diharapkan kebanyakan orang , yang biasanya adalah:

Diberikan nomor versi MAJOR.MINOR.PATCH, tambahkan:
..
Versi PATCH saat Anda melakukan perbaikan bug yang kompatibel dengan versi sebelumnya.

Saya hanya menghabiskan satu jam yang sangat tidak nyaman untuk menelusuri ini selama penerapan produksi baru.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat