在Angular中使用persitent XSRF-TOKEN cookie的风险

时间:2015-06-05 12:43:45

标签: javascript angularjs security csrf

这与此问题CSRF Protection for Refresh Token Cookie in SPA

有关

我想使用推荐的XSRF-TOKEN cookie机制来保护另一个HttpOnly cookie。对于这种情况,我需要使XSRF-TOKEN cookie持久,因为它必须在重新加载后在应用启动时可用。 Angular $http中的默认实现仅在会话cookie中查找。

如果我使cookie持久并手动设置X-XSRF-TOKEN HTTP标头会有什么风险?

3 个答案:

答案 0 :(得分:3)

  

如果我将cookie保持持久并手动设置,那么会有什么风险   X-XSRF-TOKEN HTTP标头?

风险在于攻击者最终可能会强制使用令牌值。

建议每个会话使用一个新的CSRF令牌。如果您使此持久化,则恶意站点可能会一直尝试提交包含不同令牌值的跨站点请求。最终它将尝试令牌字符的每个组合并成功发出请求。

但实际上,用户必须同时访问恶意网站。对于记住用户打开的标签并且每次都自动加载的浏览器,可能会发生这种情况。

你也可以建立一些强力保护。例如,在使用无效的CSRF令牌发出10个请求后,您可以中止会话,然后通知用户他们已经注销。这将减轻暴力攻击,但是这会将攻击转换为拒绝服务攻击,因为恶意网站将成功注销用户。因此,您应该通过联系用户并告知他们他们正在访问的网站正试图危及他们(您可以检查服务器日志以确定refererorigin标头)来跟进。 / p>

答案 1 :(得分:0)

如果您选择使用持久性Cookie,您仍然可能容易遭受CSRF攻击,因为浏览器会将这些Cookie与请求一起发送

对于angularjs,以下是我在SPA应用程序中使用的内容; CSRF令牌由后端服务器生成,仅作为标头在index.html文件的请求中传递。从那时起,angular被配置为在会话cookie中的标头+中添加令牌 - 针对每个内部$http.post/delete/put/...请求

app.config(['$httpProvider', function ($httpProvider)
{
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);

测试

使用此小片段手动测试您的api:

<!DOCTYPE html>
<html>
   <head>
        <script>
            function csrf(id)
            {
                document.getElementById("csrf-form-" + id).submit();
            }
        </script>
   </head>
   <body>
        <form method="POST" action="http://127.0.0.1:8080/api/test" enctype="text/plain" target="_blank" id="csrf-form-1">
           <input name='{"protected":false, "ignore_me":"' value='test"}'type='hidden'>  
        </form>

        <button onclick="csrf(1)"}>CSRF!</button>
   </body>
</html>

答案 2 :(得分:0)

CSRF攻击适用于用户登录的未受保护的站点。请考虑使用会话cookie C(而不是其他任何内容)来识别用户会话的站点S.这意味着浏览器会在每次请求时向S发送C.由于会话cookie的存在是确认会话所需的全部内容,因此用户将在访问S时登录。这很好。正是我们想要的。

...除

我们假设S可以是一个可以通过https://S/email-cash?email=recipient@examplecom等URL发送电子邮件的网站。一个邪恶的网站E可以在其中一个页面中嵌入链接https://S/email-cash?email=ATTACKER@examplecom。现在,当用户在登录站点S时浏览站点E并且他们点击此链接时,他们最终会通过电子邮件向攻击者发送电子邮件。更糟糕的是,这个链接可以在幕后的JavaScript中执行,因此用户只需要访问网站E.非常糟糕。

问题发生的原因是每个带有有效会话ID cookie C的请求都被视为有效请求。解决方案是要求浏览器发送一些它最近才能从站点S获得的ID。这是CSRF令牌。浏览器无法获取它,除非S由S提供,S只会在服务页面时提供,而不是跨站点攻击。

现在,如果你开始将CSRF令牌存储为持久性cookie,它就会破坏整个目的,因为它会成为浏览器在跨站点攻击时发送的东西。