将用户输入的数据传递给Queryset.filter()-安全吗?

时间:2019-04-19 15:41:56

标签: python django django-models

我有一个页面,该页面从URL中获取GET参数,并将其直接传递给REST API。因此页面网址看起来像:

foo.com/pizzas/?toppings=mushrooms&toppings=sausage

在页面加载时,它将获取GET参数并将其传递给REST API,例如:

foo.com/totally/unrelated/url/?toppings=mushrooms&toppings=sausage

在后端,我想将它们提取出来并基于它们进行过滤。这基本上就是我现在所拥有的:

# inside a django rest framework ModelViewSet
#   it's not really relevant other than that self.request exists
def get_queryset(self):
    queryset = self.model.objects.all()
    for param in self.request.query_params:
        # param = "toppings"
        if not self.is_real_model_field(param):  # assume this works
            continue
        param_value_list = self.request.query_params.getlist(param)
        # param_value_list = ['mushrooms', 'sausage']
        queryset = queryset.filter(
            f"{param}__in": param_value_list
        )
    return queryset

我已经说过,它与Django Rest Framework无关,但是我不确定100%。在上面的示例中,request.query_params由Django Rest Framework添加,但是基于DRF's documentation here,我相信它只是django内置request.GET的别名。

那么,在Django中这样做安全吗?恶意行为者可以直接操纵URL。我认为django的QuerySet.filter(field__in: values)会自动为您做一些清理工作,和/或URL的有限字符集将帮助阻止任何令人讨厌的事情的发生,但是我找不到能够讨论该问题的任何资源。

1 个答案:

答案 0 :(得分:1)

看看django_filters软件包。它可以满足您的需求,而您无需重新发明轮子。

使用此软件包,您可以列出所有可过滤的字段。该软件包还添加了查询参数值验证。