保护对抗CSRF和XSS(哈希+加密)

12 浏览
0 Comments

保护对抗CSRF和XSS(哈希+加密)

安全。如果一个应用程序没有适当的安全编程,无论是开发者使用的框架还是开发者自己,它都无法在互联网上生存。我目前正在开发一个使用Bearer令牌认证的RESTful API,但我一直在阅读关于XSS和CSRF攻击的文章。

问题1) 根据我所了解的,使用基于令牌的身份验证的RESTful API的应用程序如果将令牌存储在浏览器的localStorage/sessionStorage中而不是cookies中,那么它容易受到XSS攻击而不容易受到CSRF攻击。这是因为,要使CSRF攻击生效,应用程序必须使用cookies。我理解得对吗?

但是现在令牌存储在localStorage/sessionStorage中,应用程序容易受到XSS攻击。如果应用程序的任何部分不对输入进行合理的处理(例如,Angular的输入由框架进行了处理,但我使用的某个第三方库可能默认情况下不对输入进行处理),那么攻击者就可以注入恶意代码来窃取其他用户的令牌,然后冒充他们进行认证请求。

问题2) 有一种方法可以保护使用RESTful API的应用程序免受这两种攻击。我在这篇文章中了解到了这种方法。该文章的要点是,在用户登录并请求一个Bearer令牌时,服务器还会返回一个名为httpOnly的cookie,作为CSRFProtectionCookie。我认为这篇文章中的解决方案非常强大并提供了强大的保护。我理解得对吗?您有什么看法?

我的应用程序和上述文章中提到的方法

上述文章中提到的方法要求我将CSRFProtectionCookie持久化到某种数据库中。我不想这样做。我不希望每次向API发送认证请求时都要访问数据库。相反,我可以这样做:

登录

  1. 用户发送带有用户名和密码的POST请求到令牌端点
  2. 授权服务器验证用户凭据并开始构建带有某些声明的JWT。
  3. 作为JWT构建的一部分,它还生成一个随机字符串,并对其进行哈希处理,然后将其作为csrf声明添加到JWT中。
  4. 此外,服务器设置一个名为XSRF-TOKENhttpOnly cookie,其值是相同的随机字符串,但这次是加密的。
  5. 将响应返回给浏览器。浏览器获取到响应主体中的Bearer令牌以及设置了XSRF-TOKEN cookie。

认证请求

  1. 应用程序通过在Authorization头中添加JWT Bearer令牌来调用认证的端点。浏览器会自动发送cookie。
  2. 服务器解密cookie以获取明文。然后服务器使用JWT中的哈希验证此明文。
  3. 如果匹配,则继续请求。否则,返回未经授权的响应。

我认为这可以同时防止CSRF和XSS。因为要进行认证请求需要同时使用令牌和cookie(httpOnly)。

问题 是的,这样就不需要将任何内容持久化到数据库中了(或者需要吗?我有遗漏什么漏洞吗?)。但是每次用户请求时解密和验证哈希的开销是多少?它比数据库I/O的开销更大吗?还有其他对这种方法或其他方法的建议吗?

谢谢 🙂

0
0 Comments

CSRF(Cross-Site Request Forgery)和XSS(Cross-Site Scripting)是常见的网络安全问题,它们的出现原因和解决方法如下:

CSRF的出现原因是攻击者通过伪造请求,以受害者的身份执行恶意操作。然而,如果使用了Bearer身份验证,则CSRF攻击对于任何攻击者来说是不可能的,因为他们没有令牌值。浏览器不会自动将令牌值添加到请求中,因此Bearer身份验证对于CSRF是固有安全的。同时,如果启用了CORS(跨域资源共享),那么自定义头部将无法添加,因此也能防止CSRF攻击。API常常会启用CORS,因此通过令牌值进行API身份验证,攻击者无法知道令牌值来进行伪造请求。另外,浏览器也不会像对于基本认证、摘要认证、Cookie认证或证书认证一样,自动提供Bearer身份验证。

XSS的出现原因是攻击者在网页中插入恶意脚本,当用户访问该网页时,脚本会在用户的浏览器中执行。为了防止XSS攻击,需要确保所有的HTML输出都进行HTML编码。可以在API中对输出的HTML进行编码,或者在JavaScript中进行编码。JavaScript和一些框架如JQuery中都内置了相关的函数来帮助进行编码,比如使用textContenttext()函数。

总结起来,Bearer身份验证可以解决CSRF问题,而对于XSS问题则需要确保HTML输出进行编码。虽然XSS漏洞容易产生,但这是由于其特性决定的,开发人员需要注意HTML编码以防止XSS漏洞的产生。

0
0 Comments

问题的出现的原因:应用程序使用基于令牌的身份验证的RESTful API,如果令牌存储在浏览器的localStorage/sessionStorage中而不是cookie中,则容易受到XSS的攻击。

解决方法:使用散列和加密来保护XSS和CSRF。

从我所阅读的内容来看,我发现使用基于令牌的身份验证的RESTful API的应用程序如果将令牌存储在浏览器的localStorage/sessionStorage中而不是cookie中,则易受到XSS的攻击,而不是CSRF。这是因为,要使CSRF起作用,应用程序必须使用cookie。我理解正确吗?

基本上是正确的。如果一个应用程序仅使用cookie进行身份验证,并且没有任何CSRF保护,那么它将容易受到CSRF的攻击,因为cookie会自动包含在所有请求中。

但是现在令牌存储在localStorage/sessionStorage中,应用程序变得容易受到XSS攻击。

问题并不在于应用程序容易受到XSS攻击,而是身份验证令牌容易受到XSS攻击。如果您的身份验证令牌以http-only的方式发送,则JavaScript(以及XSS攻击)无法读取该值。

关于您的第二个问题,我认为这篇文章对如何使用会话cookie和CSRF令牌做了很好的解释。让我试着总结一下这篇文章,因为它有点长:

1. 以http-only cookie(理想情况下还要加上secure,防止浏览器在http请求中发送cookie,只能在https请求中发送)作为身份验证令牌。这样,JavaScript无法读取cookie,因此无法在XSS攻击中窃取它。

2. 使用会话存储来存储CSRF保护令牌。这样做的好处是,某些JavaScript代码必须读取此值并将其放入请求中。在某些第三方受损站点上运行的恶意代码将无法从本地存储中读取CSRF令牌,从而无法创建有效的请求。

该文章还详细介绍了如果静态资源位于与REST端点不同的域上,如何设置跨域头。

然而,您的方法与文章中所说的相反。您将身份验证令牌存储在localStorage中,并将CSRF令牌存储在cookie中。我建议将其反转回来,因为身份验证令牌比CSRF令牌更重要,而http-only secure cookie比localStorage更难以被恶意人获取。

关于您的方法,我有一些评论。

上面帖子中提到的方法要求我将CSRFProtectionCookie持久化到某种数据库中。我不想这样做。我不希望在每次向API发送经过身份验证的请求时都要访问数据库。

您的思路是正确的,这被称为“无状态CSRF令牌”。

您对“经过身份验证的请求”的方法看起来不错。我不完全确定您是否需要加密CSRF令牌值,但这并没有坏处。

您是正确的,没有漏洞。

但是每次用户请求都解密和验证哈希的开销是多少?比数据库I/O更大吗?

通常情况下,I/O比CPU密集型计算慢得多,即使是加密之类的操作也是如此。也就是说,如果您真的担心这个问题,您需要进行测量(这当然比说起来容易)。

最后的想法...

请记住,通过将CSRF令牌存储在JWT声明中,CSRF令牌将在JWT令牌的有效期内有效。即使您向客户端发送了一个新的JWT令牌,旧令牌和CSRF令牌仍然有效。这对于短暂的令牌(如10-60分钟)来说并不是什么问题,但是将CSRF令牌存储在服务器端的某个位置的好处之一是,您可以为超级敏感的操作使用一次性令牌。(此外,如果您需要撤销尚未过期的JWT令牌,您也需要在服务器端存储该状态。但是现在我们又陷入了另一个问题...)

没有特定的框架可以完全防止XSS漏洞,因为它们可以通过多种不同的方式出现。也就是说,您的Web应用程序可以使用Content-Security-Policy头来帮助防止XSS攻击。CSP头可以用于告诉浏览器可以从哪些域加载资源(如JavaScript文件)。它甚至可以用于阻止内联JavaScript的运行(这是XSS的一个主要攻击向量之一)。

我非常喜欢阅读这个答案。您仔细剖析了问题并回答了相关部分。非常感谢!至于将身份验证令牌和cookie颠倒过来 - 我没有这样做的原因。如果我需要在本地应用程序(例如Android)中使用此应用程序,那么我只能考虑请求中的身份验证令牌(我计划使用每个请求的User-Agent头来区分客户端。基于浏览器的应用程序无法修改User-Agent头,但本地应用程序可以将其设置为类似于“User-Agent:NativeApp”的内容 - 在这种情况下,忽略缺少的cookie)。

0