djnago object.get (pk = sth), как проверить, не является ли ввод вредоносным - PullRequest
0 голосов
/ 07 января 2019

Я хочу видеть моего пользователя по его идентификатору через этот маршрут:

 path('users/<int:pk>', views.UserDetail.as_view()),

и, на мой взгляд, у меня есть этот код:

users.objects.get(pk=sth)

в этом случае input (sth) проверит все идентификаторы в базе данных, чтобы проверить, существует ли input Id, и если он не найден, он вернет ошибку. проблема здесь, если пользователь вводит скрипт, который вызывает стирание базы данных, я не буду знать. Как я могу проверить, что с начала ID входные данные действительны?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

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

И еще раз поздравляю с тем, что вы выбрали одну из наиболее защищенных веб-фреймворков из всех - конечно, никакой код не гарантирован для полной защиты, но благодаря Django, следуя официальному документированному способу действий, и лучшие практики уже защитят ваш сайт. из большинства известных векторов атак (при условии, что вы постоянно обновляете все - Django и т. д., и ваш передний сервер, конечно, правильно настроен), и вы также можете рассчитывать на частые выпуски системы безопасности при обнаружении уязвимости. Единственное предостережение здесь касается django-приложений третьей части, которые могут быть неправильно закодированы, поэтому придерживайтесь тех, которые хорошо поддерживаются и имеют солидную пользовательскую базу, и даже тогда убедитесь, что вы просматриваете их исходный код на предмет возможных недостатков.

Теперь по вашему вопросу:

Ваш 'sth' уже будет впервые проверен urlresolver (частью, которая отправляет запросы http на представления в соответствии с вашим urlconf), и с учетом определения 'users/<int:pk>', что-нибудь после "users /", которое не является целое число (ну, это не соответствует \d+ регулярному выражению) будет отклонено, поэтому ваше представление никогда не будет выполнено вообще.

Тогда, даже если бы это было так, выражение User.objects.get(pk=sth) будет очищено во второй раз самой ORM, и здесь снова, если sth недопустимо для данного поля, ORM выдаст ошибку, поэтому ни один запрос не будет сделать это в базу данных - которую вы также можете проверить самостоятельно:

>>> User.objects.get(pk="delete from auth_user")
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/query.py", line 376, in get
    clone = self.filter(*args, **kwargs)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/query.py", line 796, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/query.py", line 814, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1227, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1253, in _add_q
    allow_joins=allow_joins, split_subq=split_subq,
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1187, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1083, in build_lookup
    return final_lookup(lhs, rhs)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 19, in __init__
    self.rhs = self.get_prep_lookup()
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 59, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "/home/bruno/.virtualenvs/blook/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 946, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'delete from auth_user'

И, наконец, даже если 1 / ваш URL-адрес был определен для принятия чего-либо в качестве параметра, а 2 / вы выполняли запрос к varchar или текстовому полю, orm правильно использует ваш модуль коннектора базы данных, используя параметризованный SQL-запрос , поэтому соединитель базы данных ТАКЖЕ обезвреживает параметры запроса, предотвращая внедрение SQL.

Как видите, на самом деле вам придется приложить немало усилий, чтобы обойти большую часть самого Django (в данном случае - urlresolver и ORM) и преднамеренно неправильно использовать модуль коннектора базы данных, чтобы открыть свое приложение для SQL-инъекция.

0 голосов
/ 07 января 2019

Вам не нужно беспокоиться об этих сценариях.

Подробнее: https://docs.djangoproject.com/en/dev/topics/security/#sql-injection-protection

...