【发布时间】:2021-11-13 17:26:17
【问题描述】:
他们说,通过使用 Django ORM,您已经可以抵御大多数 SQL 注入攻击。但是,我想知道是否应该或可以使用任何其他措施来处理用户输入?有没有像漂白剂这样的库?
【问题讨论】:
-
确保人们不能选择或过滤任意列名。使用一种机制来确定可以使用哪些字段。
他们说,通过使用 Django ORM,您已经可以抵御大多数 SQL 注入攻击。但是,我想知道是否应该或可以使用任何其他措施来处理用户输入?有没有像漂白剂这样的库?
【问题讨论】:
使用 Django ORM 的主要危险在于,您可能会为用户提供一个强大的工具来选择、过滤和聚合任意字段。
确实,例如,假设您制作了一个允许用户选择要返回的字段的表单,那么您可以将其实现为:
data = MyModel.objects.values(*request.GET<strong>.getlist('fields')</strong>)
如果MyModel 对名为owner 的用户模型有一个ForeignKey,那么用户可以伪造一个以owner__password 作为字段的请求,从而检索(散列)密码.虽然 Django 为其默认的 User 模型存储了一个散列密码,但这仍然意味着散列数据被公开,因此可能更容易检索密码。
但是即使没有用户模型,也可能导致用户可以在使用敏感数据链接的地方伪造请求,从而可以检索到大量敏感数据。任意过滤、注释、聚合等也会发生同样的情况。
因此,您应该做的是保留可接受值的列表,并检查请求是否仅包含这些值,例如:
acceptable = {'title', 'description', 'created_at'}
data = [field for field in request.GET.getlist('fields') if field in acceptable]
data = MyModel.objects.values(*data)
例如,如果您使用django-filter [readthedocs.io] 之类的包,您会列出可以过滤的字段以及可以对这些字段进行哪些查找。 request.GET 中的其他数据将被忽略,因此将阻止使用任意字段进行过滤。
【讨论】: