【问题标题】:prevent SQL injection in django forms防止 django 表单中的 SQL 注入
【发布时间】:2017-09-26 07:25:20
【问题描述】:

我用它来验证:

class MyValidationForm(forms.Form):
  title = forms.CharField()
  body = forms.Textarea()
  taxonomy = forms.IntegerField()

这是我基于类的视图:

class blog_createpost(dashboardBaseViews):

 template_name = "dashboardtems/blog_createpost.html"

 model = {}

 def post(self, request, *args, **kwargs):

    form = MyValidationForm(request.POST)

    if not form.is_valid():
        return HttpResponse("not valid")


    new_data = post(title=request.POST['title'],
                    body=request.POST['body'],
                    description=request.POST['description'],
                    taxonomy=get_object_or_404(taxonomy, 
                       pk=request.POST['taxonomy']),
                    writer=request.user)
    new_data.save()
    return HttpResponse("done")

就像你看到的那样,我在这一行检查了我收到的请求验证:if not form.is_valid(): 及其工作,但是当我在表单输入中添加一些 SQL-command 时。它不会阻止在数据库中插入值!.. 意味着我在数据库中有一个字段,其中包含一些值,例如select * from user where 1=1!。 它不会导致用户输入的 sql 注入危险吗?...

【问题讨论】:

  • Django 已经保护您免受 SQL 注入攻击。是的,将看起来像 SQL 命令的 data 插入到数据库中,这就是对此类数据的正确响应。成功的 SQL 注入攻击会执行 SQL,而不是将其作为数据插入。
  • 注意,使用模型表单的要点之一是您可以通过form.save() 来创建您的帖子对象。无论如何,您应该始终访问form.cleaned_data 而不是request.POST
  • 这就是我们使用 Django 等框架的原因。没有必要重新发明轮子。该框架不仅关注 SQL 注入,还关注 XSS、CSRF、表单验证等等。您应该花更多时间阅读文档并了解该工具。

标签: mysql django python-3.x sql-injection django-1.11


【解决方案1】:

您误解了 SQL 注入 的含义。 Django 已成功保护您免受此类攻击,字符串"select * from user where 1=1" 被视为数据,而不是命令,并最终成为数据库中的值。

SQL 注入攻击会改变数据库正在执行的 SQL。成功的攻击会诱使数据库将数据作为命令执行。您最终不会将 select * from user where 1=1 作为一个值,而是最终让攻击者可以访问 user 表中的所有结果。

一个典型的错误是没有通过将 SQL 命令构造为字符串来正确转义数据。假设服务器使用以下查询来查找当前用户的数据:

SELECT * FROM user WHERE username='$user_id'

$user_id 来自请求。通常那是一个登录名,比如说

user_id = "zopatista"

所以查询变成了

SELECT * FROM user WHERE username='zopatista'

如果服务器没有防范SQL注入攻击,攻击者可以替换user_id注入更多的SQL命令

user_id = "zopatista' OR 1=1 -- "

所以在简单地将该字符串插入到查询中之后,现在服务器会将以下 SQL 发送到数据库:

SELECT * FROM user WHERE username='zopatista' OR 1=1 -- '

突然查询命令的含义发生了变化,数据库将返回所有行,而不是只返回与登录名匹配的一行。

classic XKCD joke on SQL injection 更进一步,注入了 删除整个表的 SQL 代码,而不是尝试访问更多信息。

防止 SQL 注入的服务器将确保用户提供的数据始终参数化,将数据与查询分开发送到数据库驱动程序,以确保它永远不会被视为查询。

只要您使用 Django 的模型和查询集,您就可以免受 SQL 注入攻击。只有将extra()RawSQL() 与用户数据混合而不使用它们的参数功能,您才会面临风险。

【讨论】:

  • tnx ...格栅插图
  • 感谢@Martijn Pieters 的解释。目前我已经在我的视图中注入了 SQL,因为我不明白如何从 Django 模型中获取数据。我需要根据两个数据库表之间的连接提取详细信息。您能否提供一些关于如何用一些基于模型的查询替换 SQL 查询的提示?
  • @NSP:这样,太宽泛了。 Django 的 ORM 可以保护您免受注入,并且很好地支持连接。见docs.djangoproject.com/en/1.11/topics/db/queries
  • 我有这个cur.execute('''select teacher.teacher_id,teacher_name,subject_name from teacher,subject,teaches where(teacher.teacher_id=teaches.teacher_id and subject.subject_id=teaches.subject_id)''') 我怎样才能用 Django ORM 改变它?我是 django 的新手,这方面的理解相当复杂。你能建议一下吗?
  • @NSP:抱歉,不,我不会那样做。请遵循 Django 教程,它们在那里很有帮助。
猜你喜欢
  • 2013-12-26
  • 2011-06-12
  • 1970-01-01
  • 2012-11-14
  • 2011-04-30
  • 2013-02-28
  • 2011-04-25
  • 2013-03-24
相关资源
最近更新 更多