是否可以保护无状态REST API免受XSS和CSRF攻击?
目前,我使用存储在secure/httpOnlycookie中的JWT令牌进行无状态身份验证。这应该可以保护API免受最常见的XSS攻击:使用XSS注入的JavaScript窃取cookie并将其发送给攻击者。
然而,这并不能保护API免受CSRF攻击,在CSRF攻击中,攻击者会诱使经过身份验证的用户遵循特定web API调用的链接,以代表受害者启动不利交易。在不引入服务器端状态的情况下,如何保护API免受此攻击?
此外,XSS漏洞是否真的会在以下情况下允许CSRF类型的攻击:注入的JavaScript会从客户端状态、DOM或浏览器存储中检索CSRF令牌,并准备对服务器进行恶意ajax调用。浏览器仍然会自动包含相同来源请求的httpOnly cookie。除了从一开始就保护XSS漏洞之外,还有什么方法可以防止这种情况发生吗?
无状态防伪令牌
第一个问题是关于在没有服务器端状态的情况下防止CSRF。当前用于无状态防伪令牌的方法是双重提交cookie模式。
CSRF攻击依赖于浏览器自动将API自己的cookie发送回浏览器,无论请求源自何处。攻击者没有或不需要访问cookie内容。他们只需要欺骗用户加载恶意HTML。双cookie模式增加了一个新的要求:攻击者必须知道并单独发送防伪cookie的内容。
攻击者有多种方法可以用自己的方法覆盖防伪cookie。因此,您可能希望了解这种方法的一些额外的安全强化。特别是HMAC对防伪令牌进行签名,以防止令牌替换。使用HSTS和__Host
cookie前缀来确保传输安全性和正确的cookie范围。并且让客户端在自定义标头中提供防伪令牌。
自定义标头确保请求必须从JS发送,因为基于HTML标记的CSRF攻击无法设置自定义标头。从JS发送也会触发额外的保护。对于跨来源请求,它会触发浏览器上的SOP和服务器上的CORS验证。服务器还可以进行基本的原产地验证。
关于CSRF攻击的范围,下面是顶部OWASP CSRF链接的注释。
强迫受害者检索数据对攻击者没有好处,因为攻击者不会收到响应,受害者会收到。因此,CSRF攻击目标状态更改请求。
XSS问题
是的,XSS攻击可能会以这种方式发生。一旦恶意脚本被加载到JS中,它就可以自由使用Javascript可以访问的任何内容。包括应用程序代码/内存、浏览器存储和cookie。即使HttpOnly cookie不可读,它们仍然可以在请求中发送。非目标攻击可能会在流行框架使用的位置查找关键数据。并可能尝试在服务器上探测流行/可发现的API框架。有针对性的攻击意味着攻击者研究了你的系统,并为其精心设计了一个自定义负载。
XSS的主要矢量是未初始化的外部数据(用户输入、数据库值等)。要防止XSS,请从OWASP中查看这些指南。值得注意的是,Angular、React、Svelte、Vue等前端框架都内置了XSS保护。因为他们在呈现数据之前会对数据进行净化。例如:攻击者在输入中输入HTML字符串。当它稍后显示时,这些框架对字符串进行HTML编码。因此,左括号和右括号被替换为<
和>
,依此类推。这导致浏览器将字符串计算为文本,而不是可运行的HTML。但如果你不小心,你仍然可以用不同的方式把它搞砸。
XSS攻击也可能来自外部资源。可能是一个受损的CDN或NPM脚本。如果部署的代码依赖于NPM库,请格外注意NPM审核警告。一种攻击模式是附加一个小型加载程序(更容易被忽视),它将在运行时获取攻击有效载荷。CSP策略可以帮助防止这种情况。指定允许的资源列表——你的应用资产和API URL——并阻止所有其他资源。CSP还可以防止数据泄露。
对于CSRF和XSS
对于对API的攻击,您还可以使用服务器端缓解措施。基于IP的节流/临时禁令、异常活动灰名单和警报等
对于特别敏感的操作,一种策略是使用升级授权。这可以采取要求用户重新验证或使用第二个因素(如一次性密码)的形式。这可以阻止自动攻击,因为它需要主动的用户干预。
为了缓解使用现有升级授权(也可能在cookie或应用程序内存中)的攻击者,他们可能会有很短的到期时间,并且仅限于特定操作。更进一步,可以对批准的操作+相关数据进行签名。这将防止恶意脚本重复使用升级来对不同数据执行相同类型的操作。更进一步,这些敏感运算可以是幂等的。因此,如果攻击者重新发送已执行的操作,则不会对系统造成任何额外的更改。
缩小
试着把你的系统设计成尽可能让黑客不感兴趣。使用可信的外部服务满足敏感需求,如信用卡和凭据。理想情况下(从安全角度来看),黑客攻击的风险将减少到数据破坏/丢失。因此,在发生违约的最坏情况下,它几乎不会产生长期影响。它可以通过常见的做法进行恢复,包括常规测试的备份。然后针对所使用的特定攻击添加了进一步的缓解措施。
在用户与用户的交互中要特别小心。因为这为黑客增加了更多的目标和支点——你的用户群。最有安全意识的人应该关注这些碎片。不仅针对用户对用户XSS攻击等技术危险,还针对社交危险。人类的弱点是最众所周知的,也是最容易利用的。
最后,投资于在您的情况下风险/后果较低的缓解措施是没有意义的。因此,不要把这里的所有内容都当作需求清单。无论如何,这不是一个完整的列表。首先关注你最大的风险。定期重新评估。
您可以生成一个令牌(例如UUID),将其放入jwt令牌中,并将其发送回客户端。然后,客户端在每个请求期间都会在一个标头中发送它。然后,服务器可以比较头部中的令牌和jwt令牌中的令牌,以确保请求来自被授权的客户端。