前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >koa2实现网站csrf防御

koa2实现网站csrf防御

作者头像
心念
发布2023-01-11 20:53:41
9940
发布2023-01-11 20:53:41
举报
文章被收录于专栏:前端心念前端心念

什么是csrf攻击?

csrf/xsrf又叫跨站请求伪造。

先说常见的登陆鉴权: 用户在你的网站登陆后,一般把登陆凭证(token)存储在cookie里,之后每次调接口都会自动携带,后端根据这条cookie鉴权,判定是登陆状态,进而允许进行安全操作。

虽然这种鉴权方式最为简便,但存在一种安全隐患,就是csrf。

csrf攻击者会利用http请求自动携带cookie的机制,在用户登陆后,引导用户点击它的攻击链接,进而拿到用户的token去进行恶意请求,比如购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

Description
Description

防御csrf攻击

思路:

由于csrf攻击者只能拿到cookie去干坏事,但它无法知道cookie里有什么,也拿不到其他有效信息。我们只需要除cookie外再加一道它做不到的验证就可以了。

前端首次加载页面的时候,调接口让后端植入一条csrfToken到cookie里。然后前端每次请求从cookie里取出然后放到请求头里给后端传输。

后端将植入给前端的csrfToken存储在session,然后一些安全接口(一般是除了get请求外的接口),请求时,需要先进行csrf比对,取出request请求头里的csrfToken和自己session里的csrfToken进行比对,完全一致才放行

代码实现

前端(react)

代码语言:javascript
复制
1//App.tsx
2//根组件,判断cookie里有没有csrfToken,没有就请求后端种植
3  useEffect(() => {
4    if (!cookie.get("csrf_token")) {
5      request("/all/getCsrfToken");
6    }
7  }, []);
代码语言:javascript
复制
1//request.ts
2//axios请求拦截器内置了csrf方法,如下配置即可自动取出cookie里的csrf并放到请求头
3request.interceptors.request.use((config: any) => {
4  // 开启顶部加载进度条
5  Nprogress.start();
6
7  config.xsrfHeaderName = "X-CSRF-TOKEN";
8  config.xsrfCookieName = "csrf_token";
9
10  return config;
11});

后端(koa2)

后端利用koa-csrf中间件实现

代码语言:javascript
复制
1yarn add koa-csrf

1、先封装一个csrf实例

代码语言:javascript
复制
1//先封装一个csrf实例
2const CSRF = require("koa-csrf");
3
4const csrfMD = new CSRF({
5  invalidSessionSecretMessage: "Invalid session secret",
6
7  invalidTokenMessage: "Invalid CSRF token",
8
9  invalidTokenStatusCode: 403,
10});
11
12module.exports = csrfMD;

参数:

invalidTokenMessage

使 koa 抛出的错误信息内容,默认值为:"Invalid CSRF token"。它可以是一个接收 ctx 作为参数的函数,函数最后返回错误信息内容。

invalidTokenStatusCode

验证失败时的响应状态码,默认值为:403(Forbidden)。跟 invalidTokenMessage 参数一样,它也会被传递给 ctx.throw,用于抛出错误和拒绝请求。

excludedMethods

排除的请求方法,默认值为:["GET", "HEAD", "OPTIONS"]。

disableQuery

是否禁止通过查询字符串传递 _csrf 校验 token,默认值为 false。如果校验 token 出现在 URL 中,则可能会通过 Referer 泄露,应尽量把 Token 放在表单中,把敏感操作由 GET 改为 POST。

2、写一个给前端种植csrfToken的接口(必须是get)

代码语言:javascript
复制
1const Csrf = require("@utils/csrf");
2
3router.get("/getCsrfToken", Csrf, async (ctx) => {
4  ctx.cookies.set("csrf_token", ctx.csrf, {
5    httpOnly: false,
6    maxAge: 24 * 60 * 60 * 1000,
7  });
8
9  ctx.body = "csrfToken种植成功!";
10});

3、需要防御csrf的接口(post|put|delete),使用csrf即可自动校验

代码语言:javascript
复制
1router.delete("/delete",Csrf, async (ctx) => {
2  const { id } = ctx.query;
3  const result = await sql(`delete from user where id="${id}"`);
4
5  ctx.body = result;
6});
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是csrf攻击?
  • 防御csrf攻击
  • 代码实现
    • 前端(react)
      • 后端(koa2)
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com