У Django есть преимущество проверки каждого представления с помощью `method == 'POST':` - PullRequest
0 голосов
/ 22 сентября 2018

Есть ли польза от запуска каждой из моих функций просмотра с if request.method=='POST': или if request.method=='GET':?Или я просто добавил бы ненужные строки кода?

Я следовал нескольким примерам, где все представления Ajax проверяют, сделан ли HTTP с помощью GET.

Может ли это, например, не дать DDOS привязаться к методу POST и использовать GET?Или, с практической точки зрения, не допустить, чтобы потребители API неправильно патчировали, когда им нужно PUT или POST?

def employee_delete(request, uid):
    if request.method == 'DELETE':

def employee_detail(request, uid):
    if request.method == 'GET':

def employee_create(request):
    if request.method == 'POST':

def employee_update(request, uid):
    if request.method == 'PUT':

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

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

Например, универсальный CreateView уже поставляется со всей встроенной логикой для ограничения типа HTTP-запроса.Это позволит вам выполнить запрос GET для инициализации формы, но потребуется запрос POST для обработки данных.Таким образом, вы не можете случайно инициировать сохранение данных с помощью запроса GET.

Он также обеспечивает основу для правильной проверки данных формы, обработки ошибок и т. Д., Которые вы должны реализовать самостоятельно в процедурном представлении.

То же самое относится к ряду других представлений, которые предоставляет Django - UpdateView, DetailView и т. Д.

Все представления на основе классов Django поставляются с http_method_names атрибут, который вы можете использовать для контроля того, какие методы разрешены для ваших представлений, например,

from django.views.generic import View

class MyView(View):

    # only GET and POST allowed. Anything else will get a 405 Method Not Allowed response.
    http_method_names = ['get', 'post']

    def get(self, request, *args, **kwargs):
        # Logic for GET requests goes here.

    def post(self, request, *args, **kwargs):
        # Logic for POST requests goes here. No risk of it getting mixed up with GET.

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

0 голосов
/ 22 сентября 2018

Есть ли преимущество в запуске каждой из моих функций просмотра с помощью, если request.method=='POST':

Да , даже если вы поддерживаете только один метод, этолучше охранять это.Протокол HTTP указывает, что запросы GET не должны иметь побочных эффектов (хорошие эффекты в смысле подсчета посетителей, вероятно, не являются проблемой, но не то, что изменяет «сущности» вашей бизнес-логики, строго говоря, неприемлемо).

Теперь «веб-сканеры» (например, используемые поисковыми системами или скребками) обычно обнаруживают ссылки на странице и делают GET-запросы по этим ссылкам (поскольку они стремятся «обнаружить» новые страницы).Если за этим URL есть представление, например, удаляющее сотрудника, может случиться так, что случайно «веб-сканер» отредактирует вашу базу данных.

Другие методы, такие как GET, HEAD, PUT и DELETE должны иметь идемпотент (это означает, что выполнение одного и того же запроса дважды, должно иметь те же побочные эффекты, что и выполнение запроса только один раз).

Таким образом, не «защищая» свои взгляды, вы теряете слой «защиты» от случайного неправильного использования вашего веб-сервера.

Хакер может также попытаться сделать запрос другим методом и посмотреть, каксервер отвечает в поиске, чтобы найти эксплойты: например, посмотрите, делает ли сервер определенные предположения о методе, который не выполняется при выполнении запроса DELETE.Например, довольно универсальная реализация представления, которая обрабатывает все методы, может - если не защищена - непреднамеренно разрешить удаление файлов (например, вы пишете универсальное представление для создания и редактирования содержимого, которое может быть «неправильно использовано» хакером с помощью DELETE запрашивают реализацию родительского представления, но не должны поддерживаться для этого конкретного объекта).

В первые дни, например, некоторые веб-серверы HTTP не проверяли аутентификацию при использовании запроса HEAD.В результате хакер мог, попробовав несколько запросов HEAD, «просканировать» пространство идентификаторов и таким образом получить сведения о том, какие идентификаторы были заполнены в базе данных.Конечно, это само по себе не пропускает много данных, но это уязвимость, которую можно использовать в качестве первого шага для взлома данных.

Обратите внимание, что хотя Djangoимеет некоторую защиту от этого при использовании, например, представлений на основе классов, человек может просто использовать любую строку для запроса.Таким образом, человек может написать как метод FOOBAR.Если, например, представление задает if request.method == 'POST' и оператор else:, его можно использовать для ввода оператора else с помощью метода не-GET.

Но независимо от варианта использования«Лучше быть в безопасности, чем потом сожалеть», и защита методов HTTP - это лишь один из аспектов, которые нужно проверить.

При этом, если разрешено только подмножество методов, вы можете использовать @require_http_methods [Django-doc] декоратор:

from django.views.decorators.http import require_http_methods

<b>@require_http_methods(["GET", "POST"])</b>
def my_view(request):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass

Таким образом, этот декоратор делает более элегантным охранять использование надлежащего метода.

...