【前端安全】csrf

csrf:Cross Site Request Forgy 跨站请求伪造

xss主要运行了来自其他网站的脚本

csrf是打开了第三方网站 来操作之前的网站的一个行为。比如打开了一个crsf的网站,然后向刚刚那个网站发起了请求比如一个发表评论的请求,然后就评论了。

<a href="http://localhost:80/ajax/addComment?postId=13&content=点击这里有钱拿">点击这里有钱拿</a>

        <script>
            document.write(`
                <form name="commentForm" target="csrf" method="post" action="http://localhost:80/post/addComment">
                    <input name="postId" type="hidden" value="1">
                    <textarea name="content">来自CSRF!</textarea>
                </form>`
            );
            var iframe = document.createElement('iframe');
            iframe.name = 'csrf';
            iframe.style.display = 'none';
            document.body.appendChild(iframe);
            setTimeout(function(){
                document.querySelector('[name=commentForm]').submit();
            },1000);
        </script>

代码中可能打开这个网站有带有点击的引导向,或者自带一个iframe去请求对应的请求,或者是img 自带的src去请求。

csrf攻击原理:
比如三个网站,www.a.com前端,www.a.com后端,www.b.com前端。

1.首先是用户登录A网站

2.再是A网站确认用户身份

3.B网站页面向A网站发起请求(带A网站身份)


攻击部分:是第三方网站发起一个请求,headers带有cookie就可以带着身份。


CSRF攻击危害:
利用用户登录态,用户不知情,完成业务请求。盗取用户资金(转账,消费),冒充用户发帖背锅。

CSRF攻击防御:

问题:在第三步中B网站向A网站,带A网站的Cookies,不访问A网站前端,referer为B网站。

防御的措施:通过禁止第三方网站带Cookies,或者用Same-site属性。

 // 登录成功,设置cookie
            ctx.cookies.set('userId', user.id, {httpOnly:false, sameSite: 'strict'});

Same-Site有些网站不支持

让攻击者访问不到A网站的前端:

  • 在前端页面加入验证信息
  • 验证码
  • token

ccap生成图形验证码

var captcha = {};
var cache = {};
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, data);
    cache[uid] = data;
};
captcha.validCache = function(uid, data) {
    return cache[uid] === data;
};
module.exports = captcha;
    try {
        // const data = ctx.request.body;
        var data;
        if(ctx.request.method.toLowerCase() === 'post') {
            data = ctx.request.body;
        } else {
            data = ctx.request.query;
        }
        if(!data.captcha) {
            throw new Error('验证码错误');
        }
        var captcha = require('../tools/captcha');
        var captchaResult = captcha.validCache(ctx.cookies.get('userId'),data.captcha);
        if (!captchaResult) {
            throw new Error('验证码错误');
        }

Token
生成随机的字符串,让攻击者没法获得这个token

try{
    console.log('enter post');
    var csrfToken = parseInt(Math.random()*999999,10)
    const id = ctx.params.id;
}
ctx.render('post',{post, comments, csrfToken})
ctx.cookies.set('csrfToken', csrfToken)
//校验token是否一样
if(!data.csrfToken) {
    throw new Error('CSRF TOKEN 为空');
}

if(data.csrfToken !== ctx.cookies.get('csrfToken') {
    throw new Error('CSRF Token 错误');
}

页面中有一个token,也没有办法cookies,也没法改变cookies中的token.

还有一个办法:因为他第三方打开网站referer为B网站

  • 验证referer
  • 禁止来自第三方网站的请求
ctx.request.headers

其中有referer可以看到他来自的网站

var referer = ctx.request.headers.referer;
if(referer.indexOf('localhost'=== -1) {
    throw new Error('非法请求')
}
var referer = ctx.request.headers.referer;
if(!/^https?\/\/localhost/.text(referer)){
    throw new Error('非法请求');
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值