随着前后端分离架构的流行,RESTful API 已成为前端和后端进行数据交互的主要方式之一。但同时也带来了一个安全问题 - 跨站请求伪造(CSRF)攻击,即攻击者通过伪造站点提交恶意请求来欺骗用户执行某些操作。该攻击方法从理论上讲适用于任何 Web 应用程序,但特别是针对那些使用完全内部 API 的应用程序。
本文将介绍常见的 CSAF 攻击方式以及如何防止它们。主要涵盖以下内容:
- CSRF 攻击的原理和实现
- 针对 CSRF 攻击的应对策略
- 前端如何保持 CSRF 安全
CSRF 攻击的原理和实现
CSRF 攻击的一般过程如下:
- 用户在 Site-A 上进行登录,并获得一个有效的 session。
- Site-A 生成一个包含原始请求信息的 HTML 页面,其中包括一个表单提交事件,但该事件并不会直接将表单提交到 Site-A 服务器上。相反,攻击者已经修改了表单,将其提交到攻击者的服务器上。
- 攻击者服务器端收到 Site-A 页面提交的请求。
- 攻击者服务器端修改 Site-A 的请求,加入恶意代码,然后把新请求发送到 Site-B。Site-B 服务器端无法确定该请求是否来自 Site-A,于是执行了恶意请求中的操作。
如下所示的 HTML 表单是一个 CSRF 攻击的示例:
<form action="http://siteb.com/transfer" method="POST"> <input type="hidden" name="toAccount" value="1234567890" /> <input type="hidden" name="amount" value="10000" /> <button type="submit">Transfer</button> </form>
攻击的关键在于表单使用了 Site-B 的 URL,而不是 Site-A 的 URL。
针对 CSRF 攻击的应对策略
为了防止 CSRF 攻击,可以采取以下几种策略:
验证来源站点(referer 验证)
所有现代浏览器都支持 HTTP 头部字段 “Referer”。它指定了访问来源 URL,可用于防止 CSRF 攻击。服务器可使用以下方法确认请求是否来自允许的站点:
if (req.headers.referer !== "http://mysite.com/") { return res.status(403).send("Invalid referer header"); }
该策略在防止恶意伪造请求的同时,也允许允许站点之间进行数据交换。但这种方法也存在一些问题。例如,某些浏览器或浏览器插件不支持或允许修改 Referer header。
使用 Token
另一个防止 CSRF 的方法是使用 Token。应用程序要求用户提交 Token 以防止 CSRF 攻击。Token 可以在 URL 参数或 cookie 中使用。
例如,请求时包含一个名为 _csrf
的隐藏字段。服务端在处理请求之前验证 _csrf
是否正确。
<form action="/transfer" method="POST"> <input type="hidden" name="_csrf" value="j3cYydYTVI2HQzRtNNojEVw5" /> <input type="hidden" name="toAccount" value="1234567890" /> <input type="hidden" name="amount" value="10000" /> <button type="submit">Transfer</button> </form>
服务端代码如下:
app.post("/transfer", (req, res) => { if (req.body._csrf !== "j3cYydYTVI2HQzRtNNojEVw5") { return res.status(403).send("Invalid or missing CSRF token"); } // Handle transfer request });
使用 Token 的好处是,它不依赖于术语,而是针对请求的每个部分进行验证。Token 也可以更新,从而使攻击者无法再使用来自早期会话的 Token 进行 CSRF 攻击。
另一方面, Token 特定于用户会话,所以无法像基于 IP 地址的策略(例如防止 DDos 攻击)那样用于 Web 应用程序可以在不同的用户之间共享资源的情况。
同步请求
另一种防止 CSRF 攻击的方法是使所有重要操作都是同步的。而异步或非幂等的操作(例如删除或转账请求)只能由用户操作或输入 Token 来支持。该策略强制要求用户通过显式操作或输入 Token 来执行敏感操作。
前端如何保持 CSRF 安全
前端可以使用以下技术防止 CSRF 攻击:
- 使用 HTTP-only cookie:HTTP-only cookie 只能通过 HTTP/HTTPS 协议来访问,而不能通过 JavaScript 函数访问,这使得一些 CSRF 攻击无效化。
- 使用 Token:使用 Token 来防止 CSRF 攻击已成为最普遍的做法。然而,前端应确保使用的 token 独一无二,且更新频率足够快。否则攻击者有可能通过收集旧 Token 来发起新的 CSRF 攻击。
总之,在构建非常依赖于 RESTful API 的 Web 应用程序时,务必要考虑 CSRF 攻击。在现实世界中,必须采取多种方法的组合,以减少在实践中遭受 CSRF 攻击的风险。
结论
在本文中,我们介绍了 CSRF 攻击的原理和实现,并详细讨论了在 RESTful API 中如何防止这种攻击。我们介绍了一些针对 CSRF 攻击的应对策略,包括验证来源站点,使用 Token 和同步请求。
在开发 Web 应用程序时,请务必考虑 CSRF 攻击,并实现相应的预防措施,使你的应用程序可以更安全的处理与服务器之间的数据交互。
参考资料
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67393250317fbffedf159864