Django-tastypie: بحاجة إلى خيار افتراضي أكثر أمانًا: يجب ألا يسمح "DjangoAuthorization" بالوصول "للقراءة" إلى كل كائن النموذج

تم إنشاؤها على ٦ يناير ٢٠١٦  ·  10تعليقات  ·  مصدر: django-tastypie/django-tastypie

بالنظر إلى tastypie/authorization.py (حول مثل 133 - الفرع الرئيسي في 1/4/2016) ، الافتراضي ، كل من read_list و read_details تجاوز user.has_perm() الشيك ، وهو أمر غير آمن تمامًا ويعد تقصيرًا سيئًا.

افتراضي مدير Django غير تقليدي. لذلك ، استطعت أن أرى كيف أسيء تفسيره.

https://docs.djangoproject.com/es/1.9/topics/auth/default/#permissions - والإذن

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.

في الأساس ، "change_xyz" هو رمز الإذن لكل من "قراءة" و "تحديث". أعتقد أن الأفضل الافتراضي هو اتباع مدير 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

التعليق الأكثر فائدة

عند إجراء تغييرات جذرية للإنتاج ، هل يمكنك على الأقل عكس ذلك في تعيين الإصدار؟
يشبه إصدار Tastypie x.y.z إلى حد كبير ما يتوقعه معظم الناس ، وعادة ما يكون:

بالنظر إلى رقم الإصدار MAJOR.MINOR.PATCH ، قم بزيادة:
..
إصدار تصحيح عند إجراء إصلاحات أخطاء متوافقة مع الإصدارات السابقة.

لقد أمضيت للتو ساعة غير مريحة للغاية في تتبع هذا أثناء نشر إنتاج جديد.

ال 10 كومينتر

أقدر أنه تم دمج هذا بالفعل ولكن ما زلت أعترض عليه. قبل فتح طلب جديد ، إليك ما يقلقني:

يكسر هذا التغيير للأسف الكود الحالي وبالتالي فهو غير متوافق مع الإصدارات السابقة (في السابق كانت جميع طلبات GET تمر عبر DjangoAuthorization). لإصلاح الكود ، الخياران الوحيدان هما إما منح إذن التغيير لجميع المستخدمين (سيئ) ، أو ترخيص DjangoAuthoris للفئة الفرعية لتنفيذ مخصص لإجراءات القراءة (من المحتمل أن يكون هناك الكثير من العمل). هل كان هذا مقصوداً؟

إنني أقدر السبب وراء ذلك في سياق مسؤول django ، لكنني أشك في أن إعداد "قراءة" كمكافئ لـ "تغيير" في سياق واجهة برمجة التطبيقات هو افتراض افتراضي معقول لأنه ليس السلوك المتوقع. بعد كل شيء ، إذا كانت GET طريقة مسموح بها جنبًا إلى جنب مع DjangoAuthorization ، فلماذا ترفض الوصول استنادًا إلى حقيقة أن المستخدم ليس لديه إذن change ؟

أقترح اتباع تطبيق بديل:

_للقراءة_التفاصيل_

  • إذا كان النموذج يحتوي على إذن view ، فتحقق من (= التحسين لمن يحتاجون إليه)
  • إذا لم يكن هناك إذن view ، اسمح دائمًا (= متوافق مع الإصدارات السابقة)

_للقراءة_قائمة_

  • إذا كان النموذج يحتوي على إذن list ، فتحقق من (= التحسين لمن يحتاجون إليه)
  • إذا لم يكن هناك إذن list ، اسمح دائمًا (= متوافق مع الإصدارات السابقة)

بهذه الطريقة يضيف tastypie افتراضيًا متوافقًا مع الإعدادات الافتراضية لأذونات Django مع إعطاء مسار سهل للتحسين عن طريق إضافة أذونات العرض والقائمة لمن يحتاجون إليها ، بخلاف كتابة تنفيذ مخصص لـ DjangoAuthorization.

على الأقل يجب أن تكون هناك طريقة لتحديد الإذن الافتراضي:

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 سيكون من يقرر.

فقط رأيي هنا ، أعتقد أنها كانت مشكلة أمنية للسماح بالقراءة بشكل افتراضي. لم أكن أتوقع ذلك تمامًا ، حتى اقتربت جدًا من الإنتاج. أعتقد أن كسر التوافق مع الخلف أمر ضروري في هذا السياق.

يبدو أن اقتراحك يتطلب تغيير تمرير المعلمات إلى DjangoAuthorization إلى الكود الحالي الخاص بك ، في هذه الحالة ، سأعتقد أنه من الواضح فقط استدعاء الفصل بشيء آخر.

ضع في اعتبارك ، read_permission='view' case ، قد يكون هنا ما تحتاجه بالضبط. لا أرى لماذا هو أقل مثالية من

class ModifiedDjangoAuthorization(DjangoAuthorization):
    READ_PERM_CODE = 'view'

إذا كنت ترغب في تغيير الآخر ، فما عليك سوى تجاوز الطرق. تم تصميم التغيير في الواقع لتسهيل القيام بذلك.

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)

لقد أخذ التغيير في الاعتبار التعديل وجعله سهلاً. لا أعتقد أنه يجب القيام بذلك على أنه معلمات init.

أعتقد أنها كانت مشكلة أمنية للسماح بالقراءة بشكل افتراضي.

أنا لا أشكك في القصد من الإصدار الأصلي. مجرد الإشارة إلى أن التنفيذ كما تم دمجه يكسر الكود والافتراضات الحالية للأشخاص دون ذكر ذلك وبدون خيار فعال للعودة.

يبدو أن اقتراحك يتطلب تغيير تمرير البارامترات إلى تفويض Django إلى الكود الحالي الخاص بك ،

إذا نظرت إلى الحل الذي أقترحه مرة أخرى ، فإن ما أدافع عنه هو إعطاء الناس خيارات مع تقصير آمن ومتوافق مع الإصدارات السابقة. لن تكون هناك تغييرات ضرورية في رمز المستخدم في هذه الحالة.

أعتقد أن كسر التوافق مع الخلف أمر ضروري في هذا السياق.

أنا أعترض. التغيير كما هو مدمج حاليًا لا يكسر التوافق مع الإصدارات السابقة فحسب ، بل يقدم أيضًا مشكلة أمنية محتملة أكبر بكثير من حيث الطريقة الواضحة (التي ينطوي عليها التنفيذ الحالي) هي تعيين إذن التغيير لجميع المستخدمين الذين يجب السماح لهم بـ GET.

بصراحة ، أخفق في رؤية كيف أن الإذن change لإجراءات القراءة يزيد من الأمان كما في نفس الوقت يسمح هذا الإذن أيضًا PUT. لا يبدو أن خلط الأذونات لإجراءات مختلفة خيارًا جيدًا.

لسوء الحظ ، لن يؤدي ModifiedDjangoAuthorization المقترح الخاص بك إلى الحيلة ما لم تقم بالفعل بإضافة الإذن view للنموذج ، لذا فهو يكسر التوافق مع الإصدارات السابقة مرة أخرى. على الأقل يتطلب الأمر تغيير الكود - لذا فإننا نكسر التوافق مع الإصدارات السابقة _ و_ نجبر المستخدمين على إعادة صياغة قاعدة الكود الخاصة بهم.

بالطبع التجاوز هو دائمًا خيار لتحقيق المتطلبات المحددة للفرد ، ومع ذلك أعتقد أن الفكرة العامة في Tastypie هي توفير إعدادات افتراضية معقولة وآمنة لا تتطلب إضافة رمز مخصص ...

باختصار ، أعتقد أنه يجب إعادة هذا التغيير من أجل تنفيذ أفضل.

الإذن change قادم من Django نفسه. إنه الإعداد الافتراضي لـ Django ، وهو كيفية إعداد تطبيق Django Admin. الخيار view ليس كذلك. أنا شخصياً أطلقت على اسمي read .

لست متأكدًا مما تقصده بتحديد model . إذا كنت تقصد التحقق من _meta ، فقد يكون غير مكتمل. إذا كنت تقصد ضرب ديسيبل ، فقد وجدت أنها باهظة الثمن غير ضرورية.

حسب ما أفضّله ، يبدو أن ما اقترحته هو في جانب "الكثير من السحر" للحصول على إذن افتراضي. يبدو أن مجرد وجود تقصير آمن ، يمكن تجاوزه بسهولة ، كافٍ. لكن هذا مجرد رأيي.

تم توثيق التغيير هنا: https://github.com/django-tastypie/django-tastypie/blob/master/docs/release_notes/v0.13.2.rst

بصراحة ، أخفق في معرفة كيف يعمل إذن التغيير لإجراءات القراءة على زيادة الأمان حيث يسمح هذا الإذن أيضًا في نفس الوقت بـ PUT. لا يبدو أن خلط الأذونات لإجراءات مختلفة خيارًا جيدًا.

نحن نعلم أنه إذا كان بإمكان المستخدم تغيير شيء ما ، فيمكنه قراءته ، وهذه هي الطريقة التي يقوم بها مشرف Django.

هذا الإصدار أكثر أمانًا ، لأنه يجبر المطور على التفكير فيما يفعله. إذا اختار المطور ، بدلاً من اختراع إذن "القراءة" الخاص به ، منح أذونات "التغيير" للجميع عن عمد عندما يكون لديهم أذونات "قراءة" فقط ، فهذه هي مشكلتهم ؛ لا يمكنني منع المطورين الآخرين من فعل أشياء غبية عمدًا ، أنا هنا لمنع Tastypie من القيام بأشياء غبية. كان الهدف من هذا التغيير هو منع أذونات القراءة العامة على أي مورد يستخدم DjangoAuthorization ، وهو ما قد لا يتوقعه المطورون ؛ يتماشى السلوك الجديد مع تجربة المطورين في إدارة Django.

إذا كنت تريد السلوك القديم:

  1. لا تقم بالترقية إلى 0.13.2.
  2. أو قم بإلغاء الطرق read_list and read_detail`.

إذا كنت تعتقد أنه يمكن تحسين الوثائق ، فلا تتردد في تقديم تصريح إقامة.

نقدر ملاحظاتك. شكرًا للرابط المؤدي إلى المستند ، إنه أمر عادل بما فيه الكفاية ، إنه أمر سيئ لفقدان ذلك (يرجى ملاحظة أن المشكلة مخصصة للإصدار v0.13.4 بينما المستندات في الإصدار 0.13.2)

اسمحوا لي أن أبدي بعض الملاحظات الأخيرة من وجهة نظري:

نحن نعلم أنه إذا كان بإمكان المستخدم تغيير شيء ما ، فيمكنه قراءته ، وهذه هي الطريقة التي يقوم بها مشرف Django.

يستخدم مسؤول Django إذن change لأن واجهة الإدارة _is_ حول _تغيير_ الكائنات. من المنطقي هناك. طلب GET على واجهة برمجة تطبيقات REST بحكم التعريف يتعلق بقراءة / عرض. أعتقد أن معظم المطورين لا يتوقعون بكل بساطة أن يرفض ترخيص Django القراءة بناءً على إذن مفقود للتغيير.

هذا الإصدار أكثر أمانًا ، لأنه يجبر المطور على التفكير فيما يفعله.

إحدى ميزات Tastypie المُعلن عنها هي توفير _ إعدادات افتراضية معقولة_. ألن يكون من المعقول تمامًا افتراض أن أساليب GET الخاصة بواجهة برمجة التطبيقات (بحكم التعريف: قراءة) و PUT (التغيير) ، نظرًا لكونهما عمليات مختلفة في جميع النوايا والغرض ، تتطلب أيضًا أذونات مختلفة؟

سأكون سعيدًا للمساهمة في العلاقات العامة على غرار ما كتبته إذا كنتم تعتقدون أنه إضافة قيمة.

إذن التغيير قادم من Django نفسه. (...) عرض الخيار ليس كذلك.

هناك PR معلق في Django لإضافة view permission وهذا هو سبب استخدامي للعرض.

لن نسمح بعمليات القراءة العامة / العامة بشكل افتراضي. هذا نهائي. ولن نحاول تخمين كيفية إعداد أذونات المطورين عندما لا توجد حاليًا أي طريقة قياسية للقيام بذلك. لسنا متأكدين حتى مما إذا كنا سنسميها "اقرأ" أو "عرض" ، ولا أريد أن يأتي مجموعة من الأشخاص إلى هنا قائلين "أفعل ذلك بهذه الطريقة" أو "إصدار Django الجديد يطلق عليه شيئًا آخر" .

إذا ومتى دعم Django إذن قراءة / عرض خارج الصندوق ، فسننتقل إلى ذلك. في الوقت الحالي ، سيتعين على المطورين فقط كتابة بعض التعليمات البرمجية المخصصة للتعامل مع الطريقة المخصصة التي يتعاملون بها مع الأذونات.

أعلم أن هذه المشكلة مغلقة ولكني أريد فقط أن أتحدث وأقول إن هذا التغيير قد منعني بشكل أساسي من ترحيل مشروع موجود إلى 0.13.x.

@ miraculixx أعتقد أنك محق تمامًا فيما يتعلق بحقيقة أن طلب أذونات التغيير لمجرد عرض البيانات أمر مجنون بعض الشيء. أعتقد أنه يمكننا إلقاء اللوم على Django بسبب عدم امتلاكه لمفهوم إذن العرض بطريقة أو بأخرى (وهو ما يضر بي على مستوى آخر تمامًا ، أعتقد أنه من الجنون أن مشروعًا يتضمن مكون مشرف CRUD ليس لديه إذن بذلك جزء القراءة من CRUD).

عند إجراء تغييرات جذرية للإنتاج ، هل يمكنك على الأقل عكس ذلك في تعيين الإصدار؟
يشبه إصدار Tastypie x.y.z إلى حد كبير ما يتوقعه معظم الناس ، وعادة ما يكون:

بالنظر إلى رقم الإصدار MAJOR.MINOR.PATCH ، قم بزيادة:
..
إصدار تصحيح عند إجراء إصلاحات أخطاء متوافقة مع الإصدارات السابقة.

لقد أمضيت للتو ساعة غير مريحة للغاية في تتبع هذا أثناء نشر إنتاج جديد.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات