Django没有为csrftoken cookie设置HttpOnly

时间:2017-06-30 15:00:26

标签: django nginx cookies httponly

在我的Django的settings.py中我有

SESSION_COOKIE_HTTPONLY = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 15768000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SESSION_COOKIE_AGE = 2 * 24 * 3600

https://detectify.com已发现此标志未设置为csrftoken cookie。我查看了Chrome有关Cookie的信息,如果我理解正确,那么空的HTTP列会确认这两个Cookie不仅仅是HTTP:enter image description here

另外,如果我在chrome的控制台中执行document.cookie,则会显示csrftoken值。

我想知道为什么会这样。我让Django在uwsgi和nginx上运行。 nginx配置如下,相关网站为https://rodichi.net

server {
    listen 443 ssl http2 default_server;
    server_name rodichi.net;

    ssl_certificate /etc/letsencrypt/live/rodichi.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/rodichi.net/privkey.pem;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve secp384r1;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    charset     utf-8;

    ... # location settings follow here

```

1 个答案:

答案 0 :(得分:2)

您只将其配置为将CSRF令牌设置为Secure(即仅通过https请求发送)而不是HttpOnly(即不可用于Javascript)。

查看Django文档,您还需要设置CSRF_COOKIE_HTTPONLY。然而,文档正确地指出:

  

将CSRF cookie指定为HttpOnly并不提供任何实用性   保护,因为CSRF只是为了防止跨域   攻击。如果攻击者可以通过JavaScript读取cookie,那么他们就是   已经在浏览器知道的同一个域上,所以他们可以做到   无论如何他们喜欢什么。 (XSS比CSRF更大。)

     

虽然这种设置几乎没有实际效益,但有时也是如此   安全审计员要求。

这也取决于您如何实施CSRF。形式基本上有两种方法:

  1. 为每个表单设置一个隐藏的CSRF字段,并在每次加载表单时使该字段生成唯一值。因此,如果表单提交包含有效代码,那么您知道该请求来自您的域。这在服务器端很复杂,因为它需要跟踪有效令牌,并且还意味着必须动态生成每个表单以包含随机令牌,但在客户端更容易使用标准表单请求而不是JavaScript。为了保护这一点,CSRF cookie不需要,即使它存在也不使用。

  2. 另一种方法调用设置CSRF cookie,让Javascript读取它并将其发送到HTTP头(通常是X-CSRF-TOKEN)。来自其他域的CSRF请求将无法访问此CSRF cookie,因此无法正确设置标头。由于cookie也将在所有请求上发送,因此服务器很容易检查HTTP请求中的cookie与请求中设置的标头匹配。这意味着请求来自可以访问cookie的某个地方,这意味着它来自同一个域。这意味着它不是CSRF攻击。这在服务器端更容易实现(因为不需要保留活动令牌列表)但需要前端的Javascript并且需要CSRF令牌不要HttpOnly - 正是因为令牌是应该被客户端Javascript读取!

  3. 再次Django documentation warns against this

      

    如果启用此功能,则需要发送CSRF令牌的值   一个AJAX请求,你的JavaScript必须从隐藏的值中提取值   CSRF令牌表单在页面上输入而不是从cookie中输入。

    所以,总而言之,建议为此cookie设置HttpOnly属性。它限制了你,没有真正的保护,并使cookie本身毫无意义。

    您将在您网站上的Pen Test报告中突出显示它(包括https://detectify.com的外观)但应该接受,因为您觉得这是正确的。不确定是否可以在https://detectify.com中将此Cookie列入白名单,以便每次都不提醒?