使用CSRF_COOKIE_HTTPONLY将Django CSRF令牌传递给Angular

时间:2016-11-28 18:55:31

标签: angularjs django cookies csrf django-csrf

在Django中,当CSRF_COOKIE_HTTPONLY设置设置为True时,CSRF cookie获得了httponly标志,这从安全角度来看是理想的,但是打破了将此cookie添加到httpProvider的标准角度解决方案,如此:

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

通过Django 1.9,有一种解决方法,您可以将cookie直接传递给应用程序,方法是将其放入模板中:

<script>
    window.csrf_token = "{{ csrf_token }}";
</script>

将其放入角度应用中:

angularApp.config(["$httpProvider", function($httpProvider)e {
    $httpProvider.defaults.headers.common["X-CSRFToken"] = window.csrf_token;
}]

不幸的是,这对于Django 1.10+中的单页角度应用程序不起作用,因为CSRF cookie在每次请求后都会更改。如何使用CSRF_COOKIE_HTTPONLY设置从Angular发送到Django 1.10+的帖子请求? NB:禁用CSRF保护是不可接受的答案。

1 个答案:

答案 0 :(得分:0)

我认为这个问题在本次讨论中得到了很好的回答。

https://groups.google.com/forum/#!topic/django-developers/nXjfLd8ba5k

https://code.djangoproject.com/ticket/27534

CSRF_COOKIE_HTTPONLY不会为单页应用提供任何额外的安全性。有人推荐这个解决方案

var csrftoken = getCookie('csrftoken');
if (csrftoken === null) {
    csrftoken = $('input[name="csrfmiddlewaretoken"]').val();
    if (csrftoken === null) {
        console.log('No csrf token');
    }
}

然而,如果您正在为您的应用程序公开csrftoken,那么没有任何东西可以阻止恶意用户使用它并使用它。如果您正在运行单页应用程序,您可以设置CSRF_COOKIE_HTTPONLY = False,如下所示:

  

Gavin Wahl 5/4/15

     
    

怎么样?你不能只是从不同的域中获取东西。

  
     

我说的是一个域名。在页面上注入javascript   不包含CSRF令牌可以在同一个页面上获取不同的页面   领域得到它。

     
    

如果您已经将javascript注入受害者页面(XSS),则无需获取CSRF令牌,您已经获得了更大的控制权。

  
     

好吧,HttpOnly标志旨在减少攻击者的伤害   可以做一次已经可以注入javascript。但我同意 - 隐藏   来自javascript的CSRF令牌不会以任何方式增加安全性,   但文档暗示它确实如此。我想说明一下   文档说明此设置没有任何有意义的影响。

     
    

如果你仍然认为你有一个有效的攻击媒介,请发送给secu ... @ djangoproject.com并添加更多解释。

  
     

没有攻击媒介。这只是误导   文档。