启用Express,GraphQL和CORS的NodeJS CSRF保护

时间:2018-07-27 06:15:34

标签: javascript node.js api graphql csrf

我正在创建一个非常类似于shopify的Web服务,但是仅使用JS。 Nodejs表示启用了GraphQl和Cors的API。 VueJS用于前端。我的身份验证与JWT一起运行。但是我有类似匿名结帐的功能,因此我需要CSRF保护。问题是我的API不是路由器。我的路由器位于前端,只能通过Graphql通过对API的Axios调用获取我需要的数据。我看了看csurf模块并进行了尝试,但是目前我将CSRF令牌获取到前端的方法是使用我读过的API上的/ getCSRFToken端点,这不是一个好习惯,另一件事是启用了它由于启用了CORS,因此可以访问所有人。

这是我掌握的主要信息来源:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

我不知道如何在没有API路由的情况下准确地设置CSRF保护,以获取CSRF令牌并通过响应将其作为cookie发送,并且通常通过最佳实践确保整个过程的安全。

我还考虑仅对系统中商店的域限制对API的访问,但现在也行,如果这对任何人都没有好处,就不限制了。

欢迎提出任何建议

1 个答案:

答案 0 :(得分:0)

您可以生成Cookie客户端(使用window.crypto),然后让JS读取并发送到标头中,服务器只需验证它们是否匹配即可。 但是,因为cookie不是HttpOnly(因为您的JS需要读取它!),因此很容易受到攻击。因此,这种方法不是最佳实践,但总比没有好。

它也不会阻止用户发出curl的请求,并且一旦他们确定只需要提供匹配的cookie和标头,但是除非获得目标用户的授权,否则他们仍然无法代表其他用户发出请求。凭据。


使用API​​路由为每个请求生成令牌实际上没有任何问题,尽管这确实会使请求密度增加一倍(每个请求都需要一个新令牌!)。这样做的原因是,攻击者无法从外部站点读取响应(CORS会阻止这种情况)。这样一来,您就不会受到任何cookie漏洞的攻击,因为您从不首先存储cookie。

编辑:我看到您暗示已启用CORS *以便将此端点公开。如果您的API确实是公开的,那么最好使用OAuth2 / JWT身份验证,这样,CSRF就变得无关紧要了,因为身份验证不是来自Cookie。

尝试在多个请求中保留值会遇到历史记录功能的困难,因此建议您为每个请求使用令牌或...

您还可以存储来自getCsrfToken()请求的cookie,并使其保持一段时间有效,但是将其设为HttpOnly,因为它是由API发出的,因此该API将负责确保它正在接收有效的CSRF令牌。

以上两种情况的问题是,如果您想要真正的匿名性,则不能将这些令牌绑定到特定用户,因此一个用户可以通过使用自己的CSRF令牌来避免代表另一个用户进行CSRF检查! / p>

如果您可以在保持匿名的同时提出一些解决办法,则服务器可以检查接收到的令牌的有效性,以使一个用户无法代表另一个用户使用其令牌。


您的最后一个想法(假设您想要真正的匿名性)可能是最好的。如果用户代理是可信任的,则refererOrigin标头不能被篡改,因此,如果您乐意将API锁定为仅运行JS的域,则可以referer / Origin检查服务器端不会轻易受到攻击者的解决。这不是最佳做法,但实际上很有效。

再次可以自由发出卷曲请求等,但是只有在攻击者具有用户的授权凭据时,它们才能代表另一个用户发出。


最后要注意的是CSRF是XSS的替代攻击媒介,但是如果您具有XSS漏洞,则CSRF防御通常会过时,因此请确保在实施CSRF防御之前先防御XSS。