• CSRF攻击与防御


    CSRF

    Cross Site Request Forgy
    跨站请求伪造

    需要条件

    • 用户登录 A 网站
    • A 网站确认身份
    • B 网站页面向 A 网站发起请求(带 A 网站身份)

    CRSF 攻击危害

    • 利用用户登录态---盗取用户资金(转账,消费)
    • 用户不知情---冒充用户发帖背锅
    • 完成业务请求---损坏网站名誉
    • ...

    CSRF 攻击防御

    • 过程:

      • B 网站向 A 网站请求
      • 带 A 网站 Cookies
      • 不访问 A 网站的前端
      • referer 为 B 网站(这里的 referer 为为数不多的错误单词)
    • 禁止第三方网站带 Cookies,为 Cookies 设置 Same-site 属性

    koa 设置方式

    ctx.cookies.set("userId", user.id, {
      httpOnly: false,
      sameSite: "strict"
    });
    

    这种方法较好但是,有些浏览器不支持,但将来应该会的

    • 不访问 A 网站的前端
      • 在前端页面加入验证消息
      • 验证码
      • 安装第三方插件生成验证码
      • 运行npm install ccap --save
    captcha.captcha = async function(ctx, next) {
      var ccap = require("ccap");
      var capt = ccap();
      var data = capt.get();
    
      captcha.setCache(ctx.cookies.get("userId"), data[0]);
      ctx.body = data[1];
    };
    
    // 设置
    captcha.setCache = function(uid, data) {
      console.log(uid, dtat);
      cache[uid] = data;
    };
    
    //验证
    capthcha.validCache = function(uid, dtat) {
      return cache[uid] === data;
    };
    

    下面调用上面

    console.log(data.captcha);
    
    //没有验证码
    if (!data.captch) {
      throw new Erroe("验证码错误");
    }
    
    //验证码不匹配
    var captcha = require("../tools/captcha");
    var result = captcha.validCache(ctx.cookies.get("userID"), data.captcha);
    console.log("result", result);
    if (!result) {
      throw new error("验证码错误");
    }
    
    • 不访问 A 网站的前端
      • 在前端页面加入验证消息
      • token

    验证码有时是会影响用户体验的,所以就有了 taken,一般为隐藏的文本框

    var csrfToken = parseInt(Math.random() * 99999999, 10);
    ctx.cookies.set("csrfToken", csrfToken);
    
    //渲染时
    ctx.render("post", { post, comments, csrfToken });
    

    验证

    if (!data.crsfToken) {
      throw new Error("CSRF Token 为空");
    }
    if (data.csrfToken !== ctx.cookies.get("csrfToken")) {
      throw new Erroe("CSRF Token错误");
    }
    

    ajax 做法
    html 头部

    <meta http-equiv="X-UA-Compatible" content="csrfToken" name="csrf_token" />
    

    referer 为 B 网站

    • 验证 referer
    • 禁止来自第三方网站的请求
    var referer = ctx.request.header.referer;
    // console.log(ctx.request.header, referer);
    if(!^https?://loaclhost/.test(referer)){
    // if(referer.indexOf('localhost')===-1)//验证不全面,所以要采用上面的做法
      throw new Error('非法请求')
    }
    
  • 相关阅读:
    《生命3.0—在亿年的尺度下审视生命的演进》阅读笔记3
    软件杯赛题周总结(2)
    《生命3.0—在亿年的尺度下审视生命的演进》阅读笔记2
    记一次阅读源码的小经历
    11
    解决在 CSS 中,如何实现动态吸顶的样式/效果 ?
    Angular 初始化项目后,如何把默认的 .css 文件修改为 .scss 文件?
    解决 Angular 项目中,添加 <router-outlet> 标签后,报错: ‘router-outlet’ is not a known element 的问题。
    在 Angular 项目中,如何为项目单独创建路由文件?
    [NOIP2013 提高组] 《火柴排队》
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12243504.html
Copyright © 2020-2023  润新知