跳到主要内容

抵御 CSRF 攻击

概览

概览

跨站请求伪造(Cross-Site Request Forgery, CSRF)是一种攻击方式。攻击者通过诱导受害者访问一个恶意网站,在受害者不知情的情况下,向受信任网站发送伪造的请求。这些请求会沿用用户当前认证会话的凭证,从而能够利用用户的身份和权限进行破坏性操作,例如更改账户信息、删除数据等。

先决条件

  • 具备一定编程基础的开发者

接入

为了防御 csrf 攻击,我们分别在前端和后端提供了接口防御:

  • @blocklet/sdk:为后端提供了 csrf 中间件,用于验证 csrf token 。只有在成功通过验证后,系统才会正常处理相关请求。
  • @blocklet/js-sdk:为前端提供了 createAxioscreateFetch 函数,在发送请求的时候携带 csrf token

后端

@blocklet/sdk 为后端提供了 expresscsrf 中间件,用于验证 csrf token

基础用法

默认情况下,@blocklet/sdk 导出的 csrf 中间件会拦截所有含有副作用的接口(比如 POST,PUT 请求),并验证它们的 csrf token 是否有效。

如果验证失败,则会抛出错误: Current request status is abnormal, please retry later

ts
import { csrf } from '@blocklet/sdk/lib/middlewares';

app.use(csrf());

进阶用法

在某些情况下,我们也许需要根据业务逻辑,放行某些请求,此时我们可以通过自定义 csrf token 的 verifyToken 函数实现。

javascript
import { csrf } from '@blocklet/sdk/lib/middlewares';

app.use(
  csrf({
    verifyToken: async (req, res) => {
      const needVerifyToken = ...;
      if (needVerifyToken) { // only need to verify in certain cases
        await res.locals.verifyToken(req, res);
      }
    },
  })
);

前端

@blocklet/js-sdk 为前端提供了 createAxioscreateFetch 函数,在发送请求的时候携带 csrf token

基础用法

@blocklet/js-sdk 导出的 createAxios 函数,会在前端发送(含有副作用的)请求之前携带 csrf token 到请求头中。用户后端的 csrf token 中间件会对 token 进行校验,校验成功后,请求才会被处理。

javascript
import { createAxios } from '@blocklet/js-sdk';

const api = createAxios({}); // It can also be createFetch

// when making a request, the csrf token will be automatically included in request.headers['x-csrf-token']
await api.put(...);

接入成功之后,你将可以在请求头中看到 csrf-token,就像下面这样:

image.png

使用其他的前端请求库

javascript
import { getCSRFToken } from '@blocklet/js-sdk';

// Send the request with the CSRF token in the header.
request.headers['x-csrf-token'] = getCSRFToken();