防止 SQL 以 Django 形式注入

prevent SQL injection in django forms

我用它来验证:

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

这是我基于 class 的观点:

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- 用户输入的注入危险吗?...

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

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

的所有结果

一个典型的错误是没有正确转义数据,将 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 -- '

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

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

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

只要您使用 Django 的模型和查询集,您就可以免受 SQL 注入攻击。只有在不使用用户数据的情况下将 extra() or RawSQL() 与用户数据混合使用时,您才会面临风险。