Django-tastypie: Требуется гораздо более безопасное значение по умолчанию: DjangoAuthorization не должен разрешать доступ для чтения ко всем объектам модели.

Созданный на 6 янв. 2016  ·  10Комментарии  ·  Источник: django-tastypie/django-tastypie

Если посмотреть на tastypie/authorization.py (примерно 133 - главная ветка на 4 января 2016 г.), по умолчанию, как read_list и read_details обходят user.has_perm() check, что довольно небезопасно и является плохим по умолчанию.

По умолчанию администратор Django нестандартен. Итак, я мог видеть, как это было неправильно истолковано.

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.

По сути, «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

Самый полезный комментарий

Можете ли вы хотя бы отразить это в управлении версиями, когда вы вносите критические изменения?
Управление версиями x.y.z Tastypie очень похоже на то, что ожидает большинство людей , а именно:

Учитывая номер версии MAJOR.MINOR.PATCH, увеличьте:
..
Версия PATCH при исправлении ошибок с обратной совместимостью.

Я просто потратил очень неудобный час, отслеживая это во время нового производственного развертывания.

Все 10 Комментарий

Я ценю, что это уже объединено, но я все еще не согласен с этим. Прежде чем открывать новый запрос, меня беспокоит:

Это изменение, к сожалению, нарушает существующий код и, таким образом, обратно несовместимо (ранее все запросы GET проходили через DjangoAuthorization). Чтобы исправить свой код, есть только два варианта: либо предоставить всем пользователям разрешение на изменение (плохо), либо создать подкласс DjangoAuthorization для пользовательской реализации действий чтения (потенциально много работы). Это было задумано?

Я ценю аргументы, стоящие за этим в контексте администратора django, но я сомневаюсь, что установка «читать» как эквивалент «изменения» в контексте API является разумным предположением по умолчанию, поскольку это не ожидаемое поведение. В конце концов, если GET является разрешенным методом наряду с DjangoAuthorization, почему он отказывает в доступе на основании того факта, что пользователь не имеет разрешения change ?

Предлагаю следующую альтернативную реализацию:

_for read_detail_

  • если у модели есть разрешение view , проверьте это (= улучшение для тех, кому это нужно)
  • если нет разрешения view , всегда разрешать (= обратная совместимость)

_for read_list_

  • если у модели есть разрешение list , проверьте это (= улучшение для тех, кому это нужно)
  • если нет разрешения list , всегда разрешать (= обратная совместимость)

Таким образом, вкусный пирог добавляет значение по умолчанию, совместимое со значениями разрешений по умолчанию в 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 будет тем, кто решит.

Просто мое мнение здесь, я думаю, что разрешение чтения по умолчанию было проблемой безопасности. Я совершенно не ожидал этого, пока не приблизился к производству. Я думаю, что в этом контексте необходимо отказаться от обратной совместимости.

Похоже, ваше предложение требует изменения params pass на DjangoAuthorization в существующий код, в этом случае я думаю, что проще назвать класс чем-то другим.

Рассмотрим случай read_permission='view' , здесь может быть именно то, что вам нужно. Я не понимаю, почему это менее оптимально, чем

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)

Изменения действительно учитывали модификацию и упростили ее. Я не думаю, что это нужно делать как параметры инициализации.

Я думаю, что разрешение чтения по умолчанию было проблемой безопасности.

Я не подвергаю сомнению цель оригинального выпуска. Просто укажу, что объединенная реализация нарушает существующий код и предположения людей, не говоря об этом и не имея эффективной возможности вернуться.

Похоже, ваше предложение требует изменения параметров перехода к DjangoAuthorization в существующий код,

Если вы еще раз посмотрите на предлагаемое мной решение, то я за то, чтобы дать людям варианты с безопасным и обратно совместимым по умолчанию. В этом случае никаких изменений в коде пользователя не потребуется.

Я думаю, что в этом контексте необходимо отказаться от обратной совместимости.

Я не согласен. Изменение в том виде, в каком оно в настоящее время объединено, не только нарушает обратную совместимость, но также представляет гораздо большую потенциальную проблему безопасности, поскольку очевидный способ (подразумеваемый текущей реализацией) - назначить разрешение на изменение всем пользователям, которым должно быть разрешено GET.

Честно говоря, я не вижу, как разрешение change для действий чтения повышает безопасность, поскольку в то же время это разрешение также позволяет PUT. Совмещение разрешений для разных действий не кажется хорошим выбором.

К сожалению, предложенный вами ModifiedDjangoAuthorization не сработает, если вы не добавите к модели разрешение view , так что это снова нарушает обратную совместимость. По крайней мере, это требует изменения кода - поэтому мы нарушаем обратную совместимость _и_ заставляем пользователей переделывать свой код.

Конечно, переопределение - это всегда вариант для достижения конкретных требований, однако я думаю, что общая идея вкусного пирога заключается в предоставлении разумных и безопасных значений по умолчанию, которые не требуют добавления специального кода ...

Короче говоря, я думаю, что это изменение следует отменить для лучшей реализации.

Разрешение 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`.

Если вы думаете, что документацию можно улучшить, не стесняйтесь отправлять PR.

ценим ваш отзыв. спасибо за ссылку на документ, честно, плохо, что я этого не заметил (обратите внимание, что проблема назначена на v0.13.4, тогда как документы находятся в v0.13.2).

Позвольте мне сделать несколько заключительных замечаний из моего pov:

Мы знаем, что если пользователь может что-то изменить, то он может это прочитать, именно так администратор Django делает все.

Администратор Django использует разрешение change потому что интерфейс администратора _использует _ изменение_ объектов. В этом есть смысл. Запрос GET в REST API по определению касается _ чтения / просмотра_. Я думаю, что большинство разработчиков просто не ожидают, что DjangoAuthorization откажется от чтения из-за отсутствия разрешения на изменение.

Эта версия более безопасна, потому что заставляет разработчика думать о том, что они делают.

Одна из разрекламированных функций лакомства - предоставление _ разумных значений по умолчанию_. Разве не было бы разумным предположить, что методы API GET (по определению: чтение) и PUT (изменение), являясь разными операциями во всех смыслах и целях, также требуют разных разрешений?

Я буду счастлив внести свой вклад в PR в соответствии с тем, что я написал, если вы, ребята, сочтете это ценным дополнением.

Разрешение на изменение исходит от самого Django. (...) Просмотр опций - нет.

в Django есть ожидающий PR, чтобы добавить view permission поэтому я использовал view.

Мы не собираемся разрешать публичные / глобальные операции чтения по умолчанию. Это окончательно. И мы не собираемся пытаться угадать, как разработчики устанавливают свои разрешения, если в настоящее время нет какого-либо стандартного способа сделать это. Мы даже не уверены, называть ли это «читать» или «просматривать», и я не хочу, чтобы сюда приходила группа людей, говорящих: «Я делаю это так» или «в новом выпуске Django это называется как-то иначе» .

Если и когда Django будет поддерживать разрешение на чтение / просмотр из коробки, мы переключимся на это. На данный момент разработчикам просто нужно будет написать некоторый собственный код для обработки пользовательского способа обработки разрешений.

Я знаю, что эта проблема закрыта, но я просто хочу вмешаться и сказать, что это изменение фактически заблокировало мне возможность переноса существующего проекта на 0.13.x.

@miraculixx Я думаю, вы совершенно правы в отношении того факта, что требовать разрешения на изменение просто для просмотра данных - это немного безумие. Я думаю, мы можем обвинить Django в том, что у него все еще нет концепции разрешения просмотра (что взрывает мою шахту на совершенно другом уровне, я думаю, это безумие, что проект, включающий компонент администратора CRUD, просто не имеет разрешения на ЧИТАТЬ часть CRUD).

Можете ли вы хотя бы отразить это в управлении версиями, когда вы вносите критические изменения?
Управление версиями x.y.z Tastypie очень похоже на то, что ожидает большинство людей , а именно:

Учитывая номер версии MAJOR.MINOR.PATCH, увеличьте:
..
Версия PATCH при исправлении ошибок с обратной совместимостью.

Я просто потратил очень неудобный час, отслеживая это во время нового производственного развертывания.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги