脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - 详解python flask是如何预防CSRF攻击

详解python flask是如何预防CSRF攻击

2024-04-01 10:20景天科技苑 Python

CSRF(Cross-site request forgery)攻击是一种常见的网络安全漏洞,它可以通过欺骗用户执行恶意请求来攻击 Web 应用程序,本篇文章将介绍python flask是如何预防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 %}标签,那么在进行模板渲染是会生成如下标签

<input type="hidden" name="csrfmiddlewaretoken" value="ppwN8yg1wVEyXDxtMpVIrc4zV3gHiDKKb9rwGPLaSGRc0HKhXAwpNrKjGDUHIxjj">

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

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

4 取出cookie中的csrftoken值和请求数据部分的csrfmiddlewaretoken的值,两者进行比较,这个随机字符串叫做token字符串.flask如果在请求数据部分找tokne值,如果这个键对应的值和cookie中csrftoken对应的值相同,也能通过认证.

具体配置

设置应用程序的 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)

导入 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():
    html = render_template("index12.html", **locals())
    return html

@app.route("/transfer", methods=["post"])
def transfer():
    return "转账成功!"

if __name__ == '__main__':
    app.run(debug=True)

在表单中使用 CSRF 令牌

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <form action="http://127.0.0.1:5000/transfer" method="post">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
    账号:<input type="text" name="username"><br><br>
    密码:<input type="text" name="password"><br><br>
    <input type="submit" value="转账">
  </form>
</body>
</html>

浏览器访问/user页面,表单里面会多一个隐藏的input标签,

详解python flask是如何预防CSRF攻击

当我们点击转账时,form表单中只要添加了{%csrf_token%},页面就会自动添加个隐藏的input标签,每次请求得到的的value值都不相同

详解python flask是如何预防CSRF攻击

只要手动改下这个隐藏的input里面的value值,再提交数据就会forbidden。这个值只有是后台给的才能通过鉴权

详解python flask是如何预防CSRF攻击

点击转账,校验失败,数据提交不成功

详解python flask是如何预防CSRF攻击

这样,第三方请求在提交表单时,就算猜到csrf_token的变量名,也无法猜测到服务器传来的值,所以,就可以防范csrf攻击

总结

简单总结一下本文flask中CSRF攻击的防护策略:

自动防护策略:同源检测(Origin和Referer验证);

主动防护策略:token验证以及配合SameSite设置;

为了更好的防御CSRF,最佳实践应该是结合上面总结的防御措施方式中的优缺点来综合考虑,结合当前Web应用程序自身的情况做合适的选择,才能更好的预防CSRF的发生。

以上就是详解python flask是如何预防CSRF攻击的详细内容,更多关于python flask预防CSRF攻击的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/littlefun591/article/details/137146956

延伸 · 阅读

精彩推荐
  • Python利用PyCharm Profile分析异步爬虫效率详解

    利用PyCharm Profile分析异步爬虫效率详解

    这篇文章主要给大家介绍了关于如何利用PyCharm Profile分析异步爬虫效率的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用PyCharm具有一定...

    长江CJ7522021-06-24
  • Pythonpython中的元组与列表及元组的更改

    python中的元组与列表及元组的更改

    这篇文章主要介绍了python中的元组与列表及元组的更改,元组是由一对方括号构成的序列。列表创建后,可以根据自己的需要改变他的内容,下面更多详细...

    m0_6739240910772022-11-11
  • PythonScrapy中如何向Spider传入参数的方法实现

    Scrapy中如何向Spider传入参数的方法实现

    这篇文章主要介绍了Scrapy中如何向Spider传入参数的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    pengjunlee4362020-09-29
  • PythonPython自动连接SSH的实现步骤

    Python自动连接SSH的实现步骤

    本文主要介绍了Python自动连接SSH的实现步骤,可以使用paramiko模块来编写脚本自动执行SSH命令,具有一定的参考价值,感兴趣的可以了解一下...

    NSJim7782024-04-01
  • Pythonpython可以用哪些数据库

    python可以用哪些数据库

    在本篇文章里小编给大家整理的是关于python支持哪些数据库的相关知识点内容,有兴趣的朋友们可以学习下。...

    silencement4882020-06-23
  • Python书单|人生苦短,你还不用python!

    书单|人生苦短,你还不用python!

    Python 诞生之初就被誉为最容易上手的编程语言。进入火热的 AI 人工智能时代后,它也逐渐取代 Java,成为编程界的头牌语言。下面这篇文章主要给大家总结...

    脚本之家8302020-12-30
  • Python浅谈python之高阶函数和匿名函数

    浅谈python之高阶函数和匿名函数

    这篇文章主要介绍了python之高阶函数和匿名函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    strive_cogit7242021-06-08
  • PythonPython常用模块之requests模块用法分析

    Python常用模块之requests模块用法分析

    这篇文章主要介绍了Python常用模块之requests模块用法,结合实例形式分析了Python使用requests模块发送GET、POST请求及响应相关操作技巧,需要的朋友可以参考下...

    TKtalk6362021-06-26