【python】深入探讨flask是如何预防CSRF攻击的

2024-04-01 1091阅读

【python】深入探讨flask是如何预防CSRF攻击的

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑

🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。

🏆《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,面试宝典等分享。

所属的专栏:flask框架零基础,进阶应用实战教学

景天的主页:景天科技苑

文章目录

  • CSRF攻击防范
    • 插件下载
    • 工作流程
    • 具体配置
    • 完整视图代码
    • 在表单中使用 CSRF 令牌
    • 总结

      CSRF攻击防范

      详述CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

      攻击者通过HTTP请求将数据传送到服务器,从而盗取回话的cookie。盗取会话cookie之后,攻击者不仅可以获取用户的信息,还可以修改该cookie关联的账户信息。

      跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

      CSRF防范方式一:

      同源检测

      Cookie的同源和浏览器的同源策略有所区别:

      • 浏览器同源策略:协议、域名和端口都相同即同源;

      • Cookie同源策略:域名相同即同源;

        在HTTP协议中,每个异步请求都会携带两个header,用来标记来源域名:

      • Origin Header

      • Referer Header

        这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端修改,服务器接收到后可以根据这两个Header确定来源的域名;

        特殊情况: 如果Origin和Referer都不存在,建议直接进行阻止,特别是如果您没有使用随机CSRF Token(参考下方)作为第二次检查。

        另外,CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。

        CSRF防范方式二:

        添加校验token

        由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再运行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求

        CSRF: 跨域请求伪造攻击。flask预防CSRF攻击需要下载包,flask_wtf。这个就是基于token校验来防范CSRF攻击的。

        插件下载

        pip install flask_wtf
        

        flask_wtf本身提供了生成表单HTML页面的功能(基于wtforms提供),常用于开发前后端不分离的表单页面,

        同时Flask-wtf 扩展模块还提供了一套完善的 csrf 防护体系,对于我们开发者来说,使用flask_wtf模块就可以非常简单解决CSRF攻击问题。

        工作流程

        1 在表单响应的页面中加入{% csrf_token %}标签,那么在进行模板渲染是会生成如下标签

         
        

        2 并且在响应还有这个{% csrf_token %}标签的页面时,会添加cookie键值对,如下

        csrftoken:lsMQeJgVbIKKxlfz6umgYM8WOWx1Njr77cHzM0L4xtXoApsnhFXXk1OGzwb1dd0G

        3 当用户从该页面提交数据时,会携带csrfmiddlewaretoken:ppwN8yg1wVEyXDxtMpVIrc4zV3gHiDKKb9rwGPLaSGRc0HKhXAwpNrKjGDUHIxjj和cookie键值对

        4 取出cookie中的csrftoken值和请求数据部分的csrfmiddlewaretoken的值,两者进行比较,这个随机字符串叫做token字符串.

        flask如果在请求数据部分找tokne值,如果这个键对应的值和cookie中csrftoken对应的值相同,也能通过认证.

        具体配置

        1. 设置应用程序的 secret_key,用于加密生成的 csrf_token 的值
        #1. session加密的时候已经配置过了.如果没有在配置项中设置,则如下:
        app.secret_key = "#此处可以写随机字符串#"
        #2. 也可以写在配置类中。
        class Config(object):
            DEBUG = True
            SECRET_KEY = "dsad32DASSLD*13%^32"
            
        """加载配置"""
        app.config.from_object(Config)
        
        1. 导入 flask_wtf 中的 CSRFProtect类,进行初始化,并在初始化的时候关联 app
        # 方式1:
        from flask_wtf import CSRFProtect
        csrf = CSRFProtect() # 这块代码可能在文件中。
        app = Flask(import_name=__name__, template_folder="templates")
        # 项目配置代码之后
        csrf.init_app(app) # 避免出现引用导包,所以提供了init_app的用法
        # 方式2:
        # from flask_wtf import CSRFProtect
        # app = Flask(import_name=__name__, template_folder="templates")
        # 项目配置代码之后
        # CSRFProtect(app)
        

        完整视图代码

        from flask import Flask, render_template
        from flask_wtf import CSRFProtect
        csrf = CSRFProtect() # 这块代码可能在文件中。
        app = Flask(import_name=__name__, template_folder="templates")
        # 项目配置代码之后
        csrf.init_app(app) # 将插件注册到app中去
        #设置应用程序的 secret_key,用于加密生成的 csrf_token 的值
        app.config['SECRET_KEY'] = 'dafssg231bfvxvdsfwrqdqfafaffsgsbfsfsgs'
        @app.route("/user")
        def user():
            title = "用户中心"
            html = render_template("index12.html", **locals())
            return html
        @app.route("/transfer", methods=["post"])
        def transfer():
            return "转账成功!"
        if __name__ == '__main__':
            app.run(debug=True)
        

        在表单中使用 CSRF 令牌

        
        
          
          Document
        
        
          
            
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]