CSRF的理解及Flask和Django的解决方案
CSRF
攻击的原理
1. 用户正常登录 网站A
2. 网站A 向用户浏览器写入cookies(包含登录信息)
3. 用户在没有登出的情况下,访问了网站B(攻击网站)
4. 网站B 伪造了一个 网站A 的请求,诱导用户去点击
5. 用户在不知情的情况下,点击并对网站A发起请求,网站A并不清楚请求的来源,处理了这个请求,导致被攻击
如何解决?
# 在表单和cookie中,同时写入相同的token值,用户在提交表单时,验证cookie和表单中(或者请求体中)的# token是否具有,并且一致才能放行。
首先,定位问题,这是由于咱开发程序不健全导致的;
具体解决方法:
1. 后端首先需要开启第三方框架的CSRF保护,
(1) Flask框架,依赖的是 Flask-WTF 拓展。具体实现:
from flask_wtf.csrf import CSRFProtect
app.config.from_object(Config)
CSRFProtect(app)
注意:CSRFProtect只做验证工作,它对POST,PUT,DELETE和 ???请求做校验,cookie中的 csrf_token 和表单中的 csrf_token 需
要我们自己实现。
(2) Django框架,使用跨站伪造请求攻击中间件
中间件 django.middleware.csrf.CsrfViewMiddleware
在 Flask 项目中解决 CSRF 攻击实现
在 Flask 中, Flask-wtf 扩展有一套完善的 csrf 防护体系,对于我们开发者来说,使用起来非常简单
在 FlaskForm 中实现校验
- 设置应用程序的 secret_key
- 用于加密生成的 csrf_token 的值
app.secret_key = "#此处可以写随机字符串#"
- 在模板的表单中添加以下代码
<form method="post">
{{ form.csrf_token() }}
{{ form.username.label }} {{ form.username }}<br/>
{{ form.password.label }} {{ form.password }}<br/>
{{ form.password2.label }} {{ form.password2 }}<br/>
{{ form.submit }}
</form>
设置完毕,cookie 中的 csrf_token 不需要我们关心,会自动帮我们设置
单独使用
- 设置应用程序的 secret_key
- 用于加密生成的 csrf_token 的值
app.secret_key = "#此处可以写随机字符串#"
- 导入 flask_wtf.csrf 中的 CSRFProtect 类,进行初始化,并在初始化的时候关联 app
-
from flask.ext.wtf import CSRFProtect
-
CSRFProtect(app)
- 如果模板中有表单,不需要做任何事。与之前一样:
-
<form method="post">
-
{{ form.csrf_token }}
-
...
-
</form>
- 但如果模板中没有表单,你仍需要 CSRF 令牌:
-
<form method="post" action="/">
-
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
-
</form>

浙公网安备 33010602011771号