首页 文章

Cookie会保护令牌免受XSS攻击吗? [关闭]

提问于
浏览
15

我正在为基于浏览器的Javascript Web应用程序构建一个基于JWT(JSON Web Token)的身份验证机制,与无状态服务器(没有用户会话!)一起工作,我想知道,如果使用存储,一劳永逸我在cookie中的JWT令牌将保护我的令牌免受XSS攻击,或者如果没有保护,那么在我的Javascript应用程序中使用浏览器本地存储没有任何真正的优势 .

我已经在SO和许多博客中看到了这个问题并得到了回答,但我从未见过真正满足我的答案 .


这个问题最初是在征求意见的基础上进行的 - 并且考虑到我原来的措辞,这是正确的 . 因此,让我在此处明确表示,我不希望基于开发人员懒惰等模糊概念的观点 - 这就是基本规则要消除的意义 . 我想要的是证据支持的是/否答案 . 或者:

  • "Yes, cookies can be protected from XSS and CSRF and here's how" or

  • "No, by protecting your cookies from CSRF, you always open them up to the same kind of XSS attack that made cookies a good idea in the first place"


所以我要用一些简化的基本规则来重述这个问题,并提前指出漏洞,这样你,专家,可以让我直截了当 .

基本规则

  • 您的应用是一个javascript浏览器应用 - 它可能在AngularJS中,但它可能是定制的 . 它通过REST调用与服务器通信 . 比方说,jQuery $ ajax调用 .

  • 服务器是无状态的:没有会话管理 .

  • 应用程序用户JWT作为主要身份验证令牌(OAuth2用语中的“访问令牌”)并使用秘密签名密钥在服务器上验证它们

  • 忽略cookie的其他重要优点:浏览器管理,编码不良的可能性较小等 . 对于这场战斗,我想考虑绝对的安全性,并假设我们可以胜任编码任何一种机制 .

  • 忽略cookie的其他缺点,例如非浏览器应用程序等 . 对于这场战斗,我们只关注基于浏览器的JavaScript应用程序 .

  • 使用标头或请求主体以非cookie方式传输令牌无关紧要;如果您使用本地存储与会话存储也不重要 - 忽略那里的任何安全差异 . 是的,我知道技术上Cookies使用 Headers ,忽略它 .


简而言之,我们只对比较浏览器处理令牌与您的-javascript-handle-tokens以及比较XSS和CSRF安全风险感兴趣 .


参赛者

在红色角落,Auth0:本地存储击败了Cookie,因为XSS比CSRF更容易修复

在蓝色的角落,Stormpath:Cookies击败了 Headers ,因为实际上CSRF比XSS更容易修复 .

(以下详细介绍两个论点)

武器的选择

XSS和CSRF(我们将交替使用CSRF和XSRF:C似乎在文档中更受欢迎,代码中的X)

这是我对攻击类型的超简化摘要:

让我们假设您的无状态,JWT认证的javascript浏览器应用程序用于网上银行,攻击者“Evil Corp”想要提交一个AJAX REST调用,通过冒充您的用户将资金转移到他们的帐户 .

XSS(跨站点脚本)

(正如Stormpath指出的那样,有很多攻击向量 - 我会选择一个)

Evil Corp购买用于密码输入的漂亮文本字段小部件的github帐户权限 . 他们知道您的银行网站使用它,因此当您输入密码并按Enter键时,他们会更新它以提交AJAX请求以将资金转移到他们的帐户 . 您的构建系统愚蠢地提取更新并投入 生产环境 .

CSRF(跨站请求伪造)

Evil Corp知道您的银行网站使用cookie中的JWT来验证交易,因此他们编写了一个Web应用程序,提交AJAX请求以将资金转移到他们的帐户 . 他们在他们自己的evil.com网站上托管这个网站,当你碰巧在另一个标签中登录你的银行网站时,用一个电子邮件(网络钓鱼)或其他方式引诱你 . 浏览器提交来自evil.com的请求,但是附上你的JWT,因为它会进入正确的站点:银行 .

标准防御

对XSS的防御是要非常小心你的网站中的代码,以便你永远不会让浏览器处理用户键入的内容而不清理它(删除javascript和html)以及所有第三方库(Evil的文本字段小部件)在使用之前经过审查 . 正如Stormpath正确地指出的那样,这很难,接近不可能 .

对CSRF的防御是使用一种形式双重提交cookie的 . 这意味着我们的服务器创建一个令牌(安全随机的字符串)并将其发送到我们的Javascript浏览器应用程序中的可读cookie(按照惯例称为“XSRF-TOKEN”),我们的Javascript会在每个请求的头部或正文中将其发回 .

实际上,double-sumbit-cookie只是一个防御agasint CSRF,但其他一些需要有状态的服务器会话,没有其他(我认为!)提供更好的保护 . 无状态可以通过将令牌放在JWT中并将其在服务器端与头部或主体中的令牌进行比较来实现 .

但真正的CSRF破坏质量的这种防御,就是同源策略意味着只有我们的应用程序从我们的域加载的javascript才能读取该cookie . 因此,即使evilcorp.com上的javascript可以发送我们的cookie及其请求,它也无法嵌入我们的XSRF-TOKEN,因为它首先无法读取它 .

要真正简化CSRF:

  • CSRF攻击有效,因为附加cookie的浏览器仅依赖于请求的目的地 .

  • CSRF防御有效,因为Javascript访问cookie取决于Javascript的来源 .

Auth0的论点

处理XSS比使用XSRF更容易Cookies具有允许从服务器端设置HttpOnly标志的功能,因此它们只能在服务器上访问,而不能从JavaScript访问 . 这很有用,因为它可以保护注入客户端代码(XSS)访问的cookie的内容 . 由于令牌存储在本地/会话存储或客户端cookie中,因此它们会受到XSS攻击,攻击者可以访问令牌 . 这是一个有效的问题,因此您应该保持令牌过期时间不足 . 但是如果你考虑一下cookie上的攻击面,其中一个主要是XSRF . 现实情况是,XSRF是最容易被误解的攻击之一,而普通开发人员甚至可能都不了解风险,因此许多应用程序缺乏反XSRF机制 . 但是,每个人都知道什么是注射剂 . 简而言之,如果您允许在您的网站上输入然后在不转义的情况下进行渲染,那么您可以使用XSS . 因此,根据我们的经验,防止XSS比防止XSRF更容易 . 除此之外,每个Web框架都没有内置反XSRF . 另一方面,通过在大多数模板引擎上使用默认可用的转义语法,很容易防止XSS . https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies#xss-xsrf

Stormpath的论点

Stormpath建议您将JWT存储在用于Web应用程序的cookie中,因为它们提供了额外的安全性,以及使用现代Web框架防止CSRF的简单性 . HTML5 Web存储容易受到XSS攻击,具有更大的攻击面积,并且可以在成功攻击时影响所有应用程序用户 . https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

也:

我看到很多关于cookie与访问令牌相关的讨论 . 虽然我们都被在cookie中存储会话ID的系统所烧毁,但该cookie不受保护而因此被盗 . 这很糟糕,但它不是使用令牌的理由 . 这是避免非安全,非https cookie的原因 . https://stormpath.com/blog/token-auth-spa/

我的看法

Stormpath支持cookie的论点非常有说服力,但是它有一个漏洞,我没有看到它们清楚地解决:


双重提交CSRF防御依赖于我的CSRF攻击者无法访问我的cookie:其中包含XSRF-TOKEN的cookie . 但是,在本地存储的XSS攻击中,这个cookie不是那么脆弱吗?


XSS漏洞可以在我的域上运行javascript,因此它可以读取我的javascript可以使用的相同cookie . (浏览器没有't know that it isn' t我的Javascript)

从另一方面来看:本地存储受同源策略保护,就像可读cookie一样 . 如果我正在使用Auth0方法,并且XSS攻击者知道如何在本地存储中找到我的JWT并使用它 . 同一个攻击者是否可以使用相同的XSS脚本来获取我的XSRF-TOKEN cookie并使用它?

这两种攻击都要求他们阅读和理解我的javascript应用程序,但这些都在他们的浏览器中 .

那有什么区别?一个人比另一个人更安全,为什么?

1 回答

  • 4

    _Abandon希望除非你能够抵御XSS! _

    要么

    根据其他标准选择适合您的方法,因为两者都是同样安全,同样不安全 .


    如果你使用cookies,你肯定应该使用双提交cookie或类似的东西,因为它确实可以在没有XSS的情况下保护你免受CSRF的影响 . 也就是说,如果你绝对不接受CSRF攻击 - 来自其他领域 - 甚至不需要XSS漏洞就可以工作 .

    但无论哪种方式,您的源代码都是公开可用的(浏览器中的JavaScript),因此对于有动力的黑客来说,在找到从本地存储中提取哪些令牌和读取XSRF-TOKEN cookie之间的努力没有显着差异 . 如果Evil Corp可以在你的域中运行一些JavaScript - 那就是XSS - 那么你就被软管了 .

    您可能需要考虑的非安全相关标准:

    • Cookies很方便,因为您不必编写JavaScript代码来管理令牌 - 只需要XSRF .

    • 如果要使用它,重定向也会变得更加自动化 .

    • 本地存储更容易适应非浏览器应用程序 - 从服务器的角度来看,因为如果你写的是一个Java中的Android应用程序,它不想处理cookie,你的服务器不需要做任何in和浏览器之间的区别,因为它不使用cookie .

    无论如何,请自己决定,但要小心你编写的JavaScript和你使用的第三方JavaScript!

相关问题