python web框架Flask——csrf攻击

2022-10-14,,,,

csrf是什么?

  (cross site request forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为“one click attack”或者session riding,通常缩写为csrf或者xsrf,是一种对网站的恶意利用也就是人们所知道的钓鱼网站。尽管听起来像跨站脚本(xss),但它与xss非常不同,并且攻击方式几乎相左。xss利用站点内的信任用户,而csrf则通过伪装来自受信任用户的请求来利用受信任的网站。与xss攻击相比,csrf攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比xss更具危险性。

csrf可以做什么?

  你这可以这么理解 csrf 攻击:攻击者盗用了你的身份,伪装成你发送恶意请求。csrf能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

它这么厉害,那它的原理是什么?

csrf原理简述

  用户访问一个网站就会将用户的相关信息保存cookies中(session可以认为加了密的cookies,然后保存到的cookies中),这时用户又访问了一个很危险的网站,这个网站就会利用你之前访问网站留下的cookies发送一些恶意请求

csrf预防的方式

  我总结了两种预防csrf攻击的方式:后台直接处理csrf攻击(个人说法)和前端ajax请求方式

  后台处理csrf攻击

    很简单,只需要在表单中增加一个name属性值为csrf_token、value属性值为{{ csrf_token() }} 的隐藏的input表单标签。

<form class="form-signin" method="post">
        <h2 class="form-signin-heading">请登录</h2>

        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">

        <label for="inputemail" class="sr-only">邮箱:</label>
        <input type="email" id="inputemail" class="form-control" name="email" placeholder="请输入邮箱地址" required autofocus>
        <label for="inputpassword" class="sr-only">密码:</label>
        <input type="password" id="inputpassword" class="form-control" name="password" placeholder="请输入密码" required>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="remember" value="1"> 记住我
          </label>
        </div>
        <button class="btn btn-lg btn-primary btn-block" type="submit">立即登录</button>
</form>

     后台的csrftoken需要绑定到app上,这样前端表单传入的参数不会受到csrf攻击就可以像平常一样获取post参数即可(上篇python web框架flask后台登录,就是使用这种方式处理csrf攻击的)

def create_app():
    """
    主入口文件创建app,供其他蓝图使用
    :return: 返回一个app
    """
    app = flask(__name__)
    # 防止csrf注入攻击
    csrfprotect(app)
    # 注册蓝图模块
    app.register_blueprint(cms_bp, url_prefix="/cms")
    app.register_blueprint(common_bp, url_prefix="/common")
    app.register_blueprint(front_bp)

    # 导入配置文件
    app.config.from_object(config)
    # 数据库db初始化app
    db.init_app(app)
    # 后台登录login_manager初始化app
    cms_login_manager.init_app(app)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run()

 

  前端ajax请求方式

    前端ajax请求是实现页面刷新的一种非常好的方式,但是ajax请求也会有csrf攻击。防止csrf攻击也很简单,只需要两步:

      1)在当前页面上添加一个name为csrf-token, content为{{csrf_token()}}的meta标签

<meta name="csrf-token" content="{{ csrf_token() }}">

      2)重写ajax请求,并返回一个含有csrftoken的请求头

'use strict';
var cpajax = {
    "get": function(args){
        args["method"] = "get";
        this.ajax(args);
    },
    "post": function(args){
        args["method"] = "post";
        this.ajax(args);
    },
    "ajax": function(args){
        this._ajaxsetup();
        $.ajax(args);
    },
    "_ajaxsetup": function(args){
        $.ajaxsetup({
            "beforesend": function(xhr, settings){
                if(!/^(get|head|options|trace)$/i.test(settings.type) && !this.crossdomain){
                    var csrftoken = $("meta[name=csrf-token]").attr("content");
                    xhr.setrequestheader("x-csrftoken", csrftoken);
                }
            }
        });
    }
};

     3)这样前端就不能使用$.post()请求了(这种请求不能阻止csrf攻击的),而是使用我们重写的ajax请求。

$(function(){
    $("#submit").on("click", function(event){
        event.preventdefault();

        var oldpwde = $("input[name=oldpwd]");
        var newpwde = $("input[name=newpwd]");
        var newpwd2e = $("input[name=newpwd2]");

        var oldpwd = oldpwde.val();
        var newpwd = newpwde.val();
        var newpwd2 = newpwd2e.val();

        //1、要在模板中的meta标签中渲染一个csrf-token
        //2、在ajax请求的头部设置x-csrftoken
        console.log("aaaaaaa");
        cpajax.post({
            "url": "/cms/resetpwd",
            "data": {
                "oldpwd": oldpwd,
                "newpwd": newpwd,
                "newpwd2": newpwd2
            },
            "success": function(data){
                console.log(data)
            },
            "fail": function(error){
                console.log(error)
            }
        })
    })
});

 

 

 

 

 

 

 

 

  

 

《python web框架Flask——csrf攻击.doc》

下载本文的Word格式文档,以方便收藏与打印。