Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自定义REST服务的API身份验证最佳实践_Api_Security_Authentication_Xss_Csrf - Fatal编程技术网

自定义REST服务的API身份验证最佳实践

自定义REST服务的API身份验证最佳实践,api,security,authentication,xss,csrf,Api,Security,Authentication,Xss,Csrf,我会尽可能地保持这个框架的独立性,但我会参考我个人使用的框架来提供一些上下文。还有,对不起,这是一个很长的问题 上下文:我正在一个在线平台上工作。它由两个不同的服务器组成,一个“后端”提供公共REST(ish)API(在,比方说API.example.com),另一个“前端”使用Sapper(Svelte)和ssr(example.com)。后者基本上服务于API客户机 显然,某些端点与特定帐户相关,因此需要身份验证。据我所知,这有两种不同的方法,它们有不同的漏洞: 会话身份验证(cookie

我会尽可能地保持这个框架的独立性,但我会参考我个人使用的框架来提供一些上下文。还有,对不起,这是一个很长的问题

上下文:我正在一个在线平台上工作。它由两个不同的服务器组成,一个“后端”提供公共REST(ish)API(在,比方说API.example.com),另一个“前端”使用Sapper(Svelte)和ssr(example.com)。后者基本上服务于API客户机

显然,某些端点与特定帐户相关,因此需要身份验证。据我所知,这有两种不同的方法,它们有不同的漏洞:

  • 会话身份验证(cookie),易受CSRF攻击
  • 令牌身份验证(标头),易受XSS攻击(通常令牌保存在
    localStorage
    中)
直接在后端服务器上使用会话身份验证是相当困难的,因为页面由另一台服务器提供服务,并且生成/验证令牌即使不是不可能的,也不是那么容易

通用解决方案: 人们似乎对使用
localStorage
感到非常焦虑,我明白了,因为攻击者可以使用XSS窃取令牌并模拟用户。因此:

  • 将令牌存储在httpOnly cookie中
  • 每个请求都会转到example.com/api/[…]
  • 这些端点充当“代理”,从cookie中获取令牌并将其放入授权标头中,以将请求转发到API.example.com上的实际API
问题是,由于身份验证现在是通过cookie进行的(至少在“前端”级别),CSRF攻击再次成为一个问题。当然,现在处理起来更容易了,因为这都是前端服务器的责任,而且express和polka已经有了

然而,我的观点是,一般来说,CSRF令牌和CSRF保护在存在XSS漏洞的情况下是无用的,因此,即使JS无法直接访问令牌,平台仍然是易受攻击的。XSS保护仍然很重要,我们这样做毫无收获。另一方面,现在前端服务器对每个后端请求都“忙碌”,这破坏了拥有不同服务器的优势之一

我想做的基本上是坚持
localStorage
方法,但没有实际使用
localStorage
,以便利用ssr。我可以使用Sapper中间件读取cookie并将令牌存储在Sapper会话中:

sapper.middleware({
会话:(请求、恢复)=>({
授权:getCookie(req,'supersecret')//从请求中获取supersecret cookie
})
})
对于那些不了解Sapper的人来说,
session
在此上下文中基本上是一段由服务器初始化并与客户端共享的内存。使cookie httpOnly真正起不到作用,因为JS仍然可以使用会话存储访问该值。但是,由于服务器现在可以在页面重新加载期间访问令牌,我们现在可以利用ssr(在服务器上呈现从API获得的私有信息有多有用是有争议的,但为什么不呢?)

问题是:这显然不是一种标准方法,因此我不理解它可能导致(或已经造成)的问题,因为我似乎找不到任何不利之处。我在想什么/做错了什么?这真的可以吗


p.S.:如果我想使用API密钥并限制API使用,“前端代理”是强制性的,但我认为我并不真的需要它(如果我错了,请纠正我)

如果有疑问,请查看专家如何处理该问题(除非您的方法新颖)。例如,银行的安全性很高,会话寿命很短,因此用户必须每x秒重新登录一次,因此即使攻击者窃取了第一个会话密钥,在您重新验证后,他也不会拥有新会话(假设他没有窃取新会话密钥的有争议的方法)它增加了一个障碍,但不是最终的防御,因为这并不存在。 也许你还可以看看使用私钥和公钥对的非对称加密,或者独特的代码生成器,前端必须始终根据前端和后端都拥有的加密密钥生成新的密码短语,并且你必须在每个请求中发送每一个不断演变的密码,攻击者将无法通过此安全措施,除非他能够访问前端代码,这同样不是终极防御,而是攻击者的额外障碍。一种更奇特的方法是使用机器学习来识别典型的用户行为模式,并标记出普通活动,如果当前活动会话中的置信度较低,则发送警报/重新验证。

本地存储(或MemoryStorage,如果您愿意)对于产品而言永远不是一个好的解决方案。如果您只是在做一个演示或展示一个更改,那么您应该坚持使用本地存储内存缓存。将Redis用于专用缓存服务

这取决于您是否希望使用基于令牌的系统或基于会话的系统来确保服务器和客户端之间的一致性。您可以在请求中输入特定参数,以确保更好的身份(I.P.位置、更短的到期时间等)


设置https证书以使XSS攻击的效果降低。利用服务器生成的令牌确保基于会话的CSRF攻击更难执行(生成的令牌可以是非对称或对称类型)。

因此,您真正想做的是:

  • 执行无状态身份验证和授权以提高可伸缩性

    您需要在客户端上存储会话数据。您需要发送相关的