前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >CSRF跨站请求伪造保护demo

CSRF跨站请求伪造保护demo

作者头像
henu_Newxc03
发布2022-05-05 17:27:32
发布2022-05-05 17:27:32
49200
代码可运行
举报
运行总次数:0
代码可运行

源码:提取码:7uk1

一、CSRF跨站请求伪造

CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造。

CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。

包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…

造成的问题:个人隐私泄露以及财产安全。

CSRF请求伪造的示意图:

二、CSRF防护

防护思路:

1、请求转账页面的时候,服务器响应转账页面,在cookie中设置一个csrf_token值(随机48位字符串)。

2、客户端在进行post请求的时候,在请求头中带上自定义的属性’X-CSRFToken’ ,值为cookie中的csrf_token值。(要注意的是,此时的post请求,浏览器还会自发带着cookie中csrf_token到服务器。)

3、服务器在接收到post请求的时候,首先验证响应头中的x-csrftoken值,和cookies中的csrf_token是不是一致,如果不一致,需要return,直接结束处理,不进行后续工作。 完整步骤:

先安装cookie-parser

生成n为随机字符串:

代码语言:javascript
代码运行次数:0
运行
复制
function getRandomString(n){
    var str="";
    while(str.length<n){
      str+=Math.random().toString(36).substr(2);
    }
    return str.substr(str.length-n)
}
getRandomString(48);  // 调用生成csrf_token

get请求转账页面的时候,在cookie中设置一个csrf_token值(随机48位字符串): !!记得安装cookie-parser模块

代码语言:javascript
代码运行次数:0
运行
复制
if(req.method=="GET"){
    // 渲染转账页面的时候,同时在cookie中设置csrf_token
    //设置cookie和session
    let csrf_token = getRandomString(48);
    res.cookie('csrf_token', csrf_token); 

    res.render('temp_transfer');
}

接下来,在前端页面中,post请求时候带上自定义的属性’X-CSRFToken’ ,值为cookie中的csrf_token值:

代码语言:javascript
代码运行次数:0
运行
复制
$.ajax({
    url:'/transfer',
    type:'post',
    data:JSON.stringify(params),
    contentType:'application/json',
    headers:{'X-CSRFToken':getCookie('csrf_token')},
    success: function (resp) {
         ....
    }
})

....

function getCookie(name) {   //获取cookie的函数
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}

最后回到服务器端,处理post请求的时候,判断响应头中的x-csrftoken值,和cookies中的csrf_token是不是一致,不一致就是CSRF验证不通过,直接return:

代码语言:javascript
代码运行次数:0
运行
复制
...
else if(req.method=="POST"){
    // 判断响应头中的x-csrftoken值,和cookies中的csrf_token进行对比
    console.log(req.headers["x-csrftoken"]);
    console.log(req.cookies["csrf_token"]);

    if((req.headers["x-csrftoken"] === req.cookies["csrf_token"])){
        console.log("csrf验证通过!");
    }else{
        res.send("csrf验证不通过!");
        return
    }

    // 以下可以开始正常处理post请求
    ...

}

三、对每一个POST请求都设置CSRF防护

实际上,不仅仅转账需要CSRF防护,每一个post请求都需要做csrf的防护措施。

webA项目中的app.js:

代码语言:javascript
代码运行次数:0
运行
复制
const router = express.Router();

router.all('/', (req, res) => {
    if(req.method=="GET"){
        res.render('temp_login')
    }
    
    ...
});
router.all('/transfer', (req, res) => {
    
   ...
   
    else if(req.method=="POST"){
        
        let {to_account, money} = req.body;
        console.log(to_account, money);
        
        //执行转账功能: ....此处省略
        console.log("假装执行转账操作,将当前登录用户的钱转账到指定账户");
        console.log(`已经完成转账${money}元到账户${to_account}`);
        
        res.json({to_account,money});

    }
});
function csrfProtect(req, res, next){
    let method = req.method
    if(method=="GET"){
        let csrf_token = getRandomString(48);
        res.cookie('csrf_token', csrf_token);
        next() //执行跳转到下一个函数执行,即app.use(beforeReq,router)中的下一个
    }else if(method=="POST"){
        // 判断响应头中的x-csrftoken值,和cookies中的csrf_token进行对比
        console.log(req.headers["x-csrftoken"]);
        console.log(req.cookies["csrf_token"]);
        
        if((req.headers["x-csrftoken"] === req.cookies["csrf_token"])){
            console.log("csrf验证通过!");
            next()
        }else{
            res.send("csrf验证不通过!!");
            return
        }
    }
}

app.use(csrfProtect,router)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、CSRF跨站请求伪造
  • 二、CSRF防护
  • 三、对每一个POST请求都设置CSRF防护
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档