小编Rhu*_*arb的帖子

Cookie会保护令牌免受XSS攻击吗?

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

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


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

  • "是的,可以保护cookie不受XSS和CSRF的影响,这就是" 或者
  • "不,通过保护您的cookie免受CSRF的攻击,您总是将它们打开到相同类型的XSS攻击,这使得cookie首先成为一个好主意"

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

基本规则

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

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

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

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

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

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


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


参赛者

在红色角落,Auth0:Local Storage击败了Cookie,因为XSS比CSRF更容易修复

在蓝角,Stormpath:Cookies击败标题,因为实际上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)以及所有的第三方库(邪恶的文本字段部件)在使用之前经过审查.正如Stormpath正确地指出的那样,这很难,接近不可能.

对CSRF的防御是使用双提交cookie的形式.这意味着我们的服务器创建一个令牌(安全地随机字符串)和(按照惯例称之为"XSRF-TOKEN")以可读的cookie发送到我们的JavaScript浏览器的应用程序,以及我们的JavaScript的每个请求发回的标题或正文.

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

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

真正简化CSRF:

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

javascript security cookies access-token jwt

18
推荐指数
1
解决办法
2337
查看次数

Eclipse中的IProject.setDescription使用了什么设计模式

我正在设计一个具有特定模式的API,但不知道这个模式是否有名称.它与GoF(Gang of Four)中的Command模式类似,但并不完全相同.

我可以找到的一个简单示例是在Eclipse中操作项目(IProject),而不是通过调用项目上的方法来改变其状态,但是通过这个3步过程:

  1. 使用.将其状态提取到描述符对象(IProjectDescription)中getDescription
  2. 设置描述符的属性.例如setName
  3. 使用描述符描述符应用回原始项目setDescription

一般原则似乎是你有一个复杂的对象作为一个框架的一部分,具有许多可能相互依赖的属性,而不是直接在该对象上工作,一次一个属性,你将属性提取到一个简单的数据对象,操纵,并将其应用回来.

它具有Command模式的一些属性,因为数据对象封装了所有的更改,就像Command一样 - 但它实际上不是一个Command,因为你不在对象上执行它,它只是一个表示对象的状态.

它还具有Transactional API的一些属性,其中,通过使用set...调用一次性更改所有内容,如果任何一个属性更改失败,则允许整个修改有效地"回滚".虽然这是该方法的一个优点,但它并不是它的主要目的.而且,只需在API中添加事务方法(如commitrollback),就可以在没有这种方法的情况下实现事务性质.

我希望利用这种模式有两个优点 - 尽管我没有看到它们被上面的eclipse示例利用:

  1. 您可以在其实现更改时表示基础对象的有意义状态.这对于从不同类型的表示升级或复制状态非常有用.假设我发布了我的API的新版本,我在其中创建了一个对象Foo2,这是我旧的Foo1的一种全新形式,但它们都具有相同的基本属性.要将Foo1升级为Foo2,我可以将这些属性提取为FooState.foo2.setFooState(foo1.getFooState)就像那样.解释和表示属性的方式封装在Foos中,可以完全不同.

  2. 我可以使用我的简单数据对象持久化并传输底层对象的状态,其中持久化对象本身会复杂得多.因此,我可以将Foo的状态提取为FooState,并将其保存为简单的XML文档,然后通过"加载"并应用它将其应用于某个新对象.或者我可以将FooState简单地作为JSON对象传输到web服务,而Foo本身太大而且传输复杂.(或者服务调用每一端的对象完全不同,如Foo1和Foo2)

无论如何,我无法在任何地方找到这种模式的名称或例子,无论是在Gang of Four设计模式中,甚至在Martin Fowler的全面"bliki"中也是如此.

api design-patterns

5
推荐指数
1
解决办法
124
查看次数