开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
在web安全导致,表单提交数据的安全尤为重要,之前通过表单校验,已经过滤了一部分非法提交的数据,但是在提交数据的过程当中还是有一个风险的,就是跨域请求伪造登录,我们举个例子:
1)假设用户打开了一个银行网站,并且登录了 2)登录成功后,会返回一个cookie给前端,浏览器将cookie保存下来 3)用户在没有登出银行网站的情况下,在当前浏览器又新打开多了一个选项卡,访问了一个危险的网站 4)这个网站有个危险的超链接,这个超链接指向了银行网站 5)用户点击这个超链接,由于这个超链接会自动携带上cookie,所以用户不知不觉在点击这个超链接的时候,还要一些请求是发到了银行网站那里去。
Flask CSRF防御
防御原理
flask 本身没有对csrf的预防策略,但是flask-wtf模块插件是有的,这个原理就是:
1)在渲染的表单上添加一个隐藏的表单域,设置一个加密值 csrf_token,这个值只在当前页面下发。
2)然后表单提交的时候顺带提交,服务端如果校验不是这个值,证明提交的来源不是当前页面,就拒绝请求。
这样就可以防止请求不是从页面上来,(当然,如果在渲染页面完成之后,获取到token值,然后携带也可以跳过页面进行请求,但是如果对方不是人为调整,而是js端恶意跳转的话,已经主够防御了。)
配置步骤
安装flask-jwt
pip install Flask-WTF
csrf导入和配置
from flask import Flask,render_template
from flask_wtf import CSRFProtect
app = Flask(__name__)
app.secret_key = "abcdefghijklmnopqrstuvwsyz" #设置token加密的盐值
csrf = CSRFProtect() #创建csrf实例
csrf.init_app(app) #csrf实例绑定到app上
@app.route("/index")
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
前端使用csrf
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>csrf案例</title>
</head>
<body>
<form action="" method="post">
<input type="hidden" name="csrf_token" value="{{csrf_token()}}">
账号:<input type="text" name="username"><br><br>
密码:<input type="password" name="password"><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
关闭CSRF保护
其实有的请求是不需要csrf保护的,所以可以进行csrf关闭:
全局关闭
app.config中设置WTF_CSRF_ENABLED = False
单个表单不使用csrf保护
单个表单禁用:生成表单时加入参数form = Form(csrf_enabled=False)
单个视图添加csrf保护
在不需要保护的路由上当加上: @csrf.exempt