在视图GET方法上使用@csrf_protect

时间:2013-04-02 01:01:03

标签: django python-2.7 django-views django-csrf django-1.5

我的大多数GET请求都是由Angular触发的,这样可以很容易地在标头中设置CSRF令牌。这已经开箱即用于POST请求,但是我想知道我是否也可以对GET请求使用CSRF保护。

我最初的直觉是在View的get方法之前添加@csrf_protect,例如:

class ProjectView(View):
    @csrf_protect
    def get(self, request, *args, **kwargs):
        ...

然而,这会产生错误:

AttributeError at /project
'ProjectView' object has no attribute 'COOKIES'

File "c:\Apps\msysgit\simpletask\lib\site-packages\django\middleware\csrf.py" in process_view
  95.                 request.COOKIES[settings.CSRF_COOKIE_NAME])

所以我猜测POST请求提供的内容与GET请求不同。有更好的方法吗?

此外,在任何人提到所有敏感信息都应该通过POST请求提取之前(我最近已经看过几次),我试图坚持使用GET的原因是我正在尝试根据RESTful指南构建,意思是GET请求用于提取数据,POST用于新记录,PUT用于更新,DELETE用于删除数据。

修改

由于似乎有一种情绪我不应该尝试上述内容,而我现在确实同意了,我试图阻止的漏洞在这三个链接中讨论:

2 个答案:

答案 0 :(得分:7)

我认为您不太了解CSRF实际上保护的内容。 CSRF利用网站对用户浏览器的信任;通过利用允许攻击者代表用户运行命令的会话cookie。

该站点信任该请求,因为它尚未使浏览器的会话cookie过期。这就是为什么在大多数CSRF缓解技术中,为每个具有副作用的请求生成唯一的OTP。攻击者不会知道为OTP生成的密钥,因此无法伪造合法请求。

对于所有具有副作用的URL(如POST,PUT,DELETE),您需要CSRF。对于GET而言,拥有它没有任何意义,因为GET请求 - 如果你正确地执行REST - 应该是幂等的 - 如果多次运行,它们会返回相同的结果而它们不应该有任何副作用。

CSRF保护不会阻止信息泄露或中间人攻击。因此,如果您要保护敏感信息,请使用HTTPS。为防止不受管制地使用您的API,请使用身份验证和授权。

答案 1 :(得分:4)

您需要使用method_decorator

https://docs.djangoproject.com/en/1.4/topics/class-based-views/#decorating-the-class

所以你的代码将是

class ProjectView(View):`
    @method_decorator(csrf_protect)
    def get(self, request, *args, **kwargs):

<强> [编辑] 但是csrf_protect只检查POST请求(它有`if request.method =='POST'检查)所以你必须自己实现一些东西。