djnago object.get(pk = sth),如何检查输入是否不是恶意的

时间:2019-01-07 08:22:37

标签: django django-rest-framework

我想通过此路线通过其ID看到我的用户:

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

在我看来,我有以下代码:

users.objects.get(pk=sth)

在这种情况下,输入(sth)将使用数据库中的所有ID进行检查,以检查输入ID是否存在,如果找不到,则将返回错误。 问题出在这里,如果用户输入导致删除数据库的脚本,我将不知道。如何从头开始检查id输入数据是否有效?

2 个答案:

答案 0 :(得分:5)

答案 1 :(得分:3)

首先,祝贺您担心安全问题,这是很多“网络开发人员”似乎完全忽略的事情-对我们最终用户而言。

也恭喜您选择了最安全的Web框架之一-当然,没有任何代码可以保证绝对安全,但是Django仅遵循官方记录的处理方式,并且最佳实践已经可以保护您的网站从大多数已知的攻击媒介(假设您保留所有内容-Django等-是最新的,并且当然对前端服务器进行了正确配置),并且当检测到漏洞时,也可以依靠频繁的安全发布。唯一需要注意的是有关第3部分django应用程序的可能未正确编码,因此请坚持使用维护良好并拥有可靠用户基础的django应用程序,甚至还要确保您浏览其源代码以查找可能的缺陷。

现在wrt /您的问题:

您的“ thth”将已经由urlresolver(根据您的urlconf向视图分配HTTP请求的部分)进行第一次验证,并赋予'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被定义为可以接受任何参数作为param,并且2 /您在varchar或text字段上进行查询,orm也会通过使用{来正确使用数据库连接器模块。 {3}},因此数据库连接器还将清理查询参数,防止SQL注入。

如您所见,您实际上必须付出很多努力来绕过大多数Django本身(在这种情况下为urlresolver和ORM),并故意错误地使用数据库连接器模块以将应用程序打开到SQL注入。