Express.js 中的跨站请求伪造(CSRF)防御机制详解

什么是 CSRF 攻击?

跨站请求伪造(CSRF)攻击是一种利用用户在已登录的网站上的身份验证信息,通过伪造用户的请求来执行未经授权的操作的攻击方式。攻击者可以通过诱骗用户点击恶意链接或者在用户浏览器中注入恶意代码来实现此类攻击。如果目标网站没有防范措施,攻击者可以利用 CSRF 攻击来执行一系列危害性的操作,例如修改用户账户信息、发起钓鱼攻击等。

CSRF 攻击的原理

下面通过一个简单的例子来说明 CSRF 攻击的原理。假设有一个银行网站,用户在该网站上登录后,可以进行转账操作。转账页面的 HTML 代码如下:

----- ------------------ --------------
  ------ ------------- --------- ------------------
  ------ ------------- ------------- -------------
  ------- -------------------------
-------

用户在登录后,访问了一个恶意网站,该网站中包含如下代码:

---- --------------------------------------------------------- --

当用户访问该网站时,浏览器会自动发送请求到银行网站进行转账操作。由于用户已经在银行网站上登录,浏览器会自动带上用户的身份验证信息,从而使得攻击者可以伪造用户的请求,执行转账操作。

CSRF 攻击的防御

为了防止 CSRF 攻击,我们需要在服务器端对请求进行验证,确保请求是来自合法的源。常见的防御方式包括:

1. 验证 HTTP Referer 头

HTTP Referer 头记录了当前请求的来源 URL,我们可以通过验证该头部信息来确保请求是来自合法的源。但是该方式存在一些问题:

  • 有些浏览器或者防火墙会禁用或者篡改该头部信息。
  • HTTP Referer 头是可信任的,攻击者可以通过伪造 Referer 头来通过验证。

因此,该方式并不是可靠的防御方式。

2. 验证 CSRF Token

CSRF Token 是一种在服务器端生成的随机字符串,每次请求时需要将该字符串带上,服务器端验证该字符串是否合法。攻击者无法获取到该字符串,因此无法伪造请求。该方式是目前比较可靠的防御方式。

在 Express.js 中,我们可以通过 csurf 模块来添加 CSRF 防御机制。该模块会自动生成 CSRF Token,并将该 Token 添加到响应头部中,同时在每个表单中添加一个隐藏的 input 标签,用于存储该 Token。在服务器端验证请求时,我们可以通过 csurf 模块提供的中间件函数来验证 CSRF Token。

----- ------- - -------------------
----- ---- - -----------------
----- ---------- - -----------------------

----- --- - ----------
----- -------------- - ------ ------- ---- ---
------------------------------- --------- ----- ----
------------------------

-------------------- ----- ---- -- -
  ----------
    ----- ------------------ --------------
      ------ ------------- ------------ ---------------------------
      ------ ------------- --------- ------------------
      ------ ------------- ------------- -------------
      ------- -------------------------
    -------
  ---
---

--------------------- ----- ---- -- -
  -- --------------- --- ---------------- -
    ------ ----------------------------- ---- --------
  -
  -- ------
  ------------------ ----------
---

---------------- -- -- ------------------- ------- -- ---- --------

在上面的例子中,我们首先创建了一个 csrfProtection 中间件,通过 csrf 函数来生成 CSRF Token,并将该 Token 存储在 Cookie 中。然后在每个表单中添加一个隐藏的 input 标签,用于存储该 Token。在处理 POST 请求时,我们可以通过 req.body._csrf 来获取表单中提交的 CSRF Token,并与 Cookie 中存储的 Token 进行比对。如果两者不一致,说明该请求可能是伪造的请求,我们可以返回 403 状态码,拒绝该请求。

总结

CSRF 攻击是一种常见的网络攻击方式,可以通过伪造用户的请求来执行未经授权的操作。为了防止 CSRF 攻击,我们可以在服务器端对请求进行验证,常见的防御方式包括验证 HTTP Referer 头和验证 CSRF Token。在 Express.js 中,我们可以通过 csurf 模块来添加 CSRF 防御机制,该模块会自动生成 CSRF Token,并在服务器端对请求进行验证,从而防止 CSRF 攻击的发生。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65f3d99a2b3ccec22fc45c42