解决单页应用程序中的 CSRF 攻击问题
什么是 CSRF 攻击?
CSRF(Cross-Site Request Forgery)跨站请求伪造,是一种常见的网络攻击方式之一,也被称为“One-Click Attack”或者Session Riding。攻击者通过伪造页面或者图片让受害者在已经登录的情况下,误以为是在进行正常的操作,然后将操作结果发送到攻击者指定的网站,以达到攻击者的目的。
下面我们以一个银行应用程序为例来理解 CSRF 攻击的过程:
- 假设你已经登录到你的银行应用程序并开始你的工作。
- 攻击者向你发送一封伪造的邮件,并在邮件中嵌入了一个链接,这个链接会跳转到银行的某个网页,例如汇款页面,其中隐藏着一些恶意代码。
- 在你点击链接之后,由于你已经在银行应用程序上登录,因此你的浏览器会自动发送银行汇款请求,而这个请求并不是你自己提出的请求,而是攻击者通过邮件中嵌入的链接触发的。
- 银行服务器会认为这个请求是合法的并对其进行处理,然后将汇款转账到攻击者指定的账户上。
可以看出,攻击者利用了你当前已经登录的用户权限完成了非法操作,并以你的名义向银行提交了请求。这就是 CSRF 攻击的基本原理。
单页应用程序中的 CSRF 攻击
在单页应用程序中,页面内容是由 JavaScript 动态生成的,在用户和服务器之间的交互是通过 AJAX 来完成的。这样的应用程序在与后台 API 交互时,很容易受到 CSRF 攻击的影响。
下面以一个简单的单页应用为例,来看看如何构造一个 CSRF 攻击:
<!-- index.html --> <body> <button id="transferBtn">转账 $100</button> <script src="./index.js"></script> </body>
-- -------------------- ---- ------- -- -------- ---------------------------------------------------------------- -- -- - ------------------ - ------- ------- -------- - --------------- ------------------ -- ----- ---------------- --- ----------------- ------- --- -- ---------- -- - --------------- ----------- -- - --------------- --- ---
在这个示例中,我们通过 AJAX 请求向后台服务器发送了一个转账请求,其中包含了目标账户和转账金额。如果我们不做任何防范措施,那么攻击者可以通过构造一个同样的请求并发送到你的用户上,从而完成一个 CSRF 攻击。
如何防范 CSRF 攻击
针对 CSRF 攻击,我们可以采取以下措施来防范:
- 验证来源域名:可以在后台服务器中验证每个请求的源域名是否与当前网站的域名一致。如果不一致,那么这个请求就是非法的,应该拒绝处理。
- CSRF Token 验证:在跨站请求的时候,需要携带一个唯一的 CSRF Token 属性,在服务端进行验证。(参考:mdn官方文档) 在请求完成后,每次重置这个 Token 的值。
- SameSite Cookie 属性:浏览器提供了 SameSite Cookie 属性,该属性可以控制 Cookie 的跨站行为,默认是关闭的,我们可以通过设置为 Lax 或者 Strict 来控制它的行为,例如 Lax 就表示只允许 get 方法而非 post 方法跨站的 cookie 也带上。
在单页应用中,由于应用是基于 JavaScript 构建的,所以我们可以在应用代码中添加一个 CSRF Token 参数,每次向后台服务器提交请求时都要携带这个值。
下面来看一下示例代码:
<!-- index.html --> <body> <button id="transferBtn">转账 $100</button> <script src="./index.js"></script> </body>
-- -------------------- ---- ------- -- -------- ---------------------------------------------------------------- -- -- - ------------------ - ------- ------- -------- - --------------- ------------------- --------------- -------------- -- ------- ---- ----- -- ----- ---------------- --- ----------------- ------- --- -- ---------- -- - --------------- ----------- -- - --------------- --- --- -- -- ---- ----- - -------- -------------- - --- ----- - ----------------------------------- -- -------- - ----- - ---------------------------------------- ---------------------------------- ------- - ------ ------ -
在这个示例中,我们通过 localStorage 来存储 CSRF Token,如果用户已经有了 Token,那么我们直接拿取;否则,我们随机生成一个 Token 并保存到 localStorage 中。
这里需要注意的是,我们将 CSRF Token 存储在 localStorage 中,而不是在 Cookie 中,这是因为在单页应用程序中,Cookie 存储的数据量是有限制的。而 localStorage 可以存储比 Cookie 更大的数据量,且默认不会发送到服务器。
总结
CSRF 攻击在网络中非常常见,竞争对手和黑客都会尝试使用该攻击方式窃取用户的数据和信息。对于单页应用程序,我们可以采取措施防范 CSRF 攻击,例如验证来源域名、使用 CSRF Token 和设置 SameSite Cookie 属性。
希望这篇文章对大家学习前端开发有所指导和帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64646315968c7c53b0541171