19、Flask实战第19天:CSRF攻击与防御
CSRF攻击原理
网站是通过cookie来实现登录功能的。而cookie只要存在浏览器中,那么浏览器在访问这个cookie的服务器的时候,就会自动的携带cookie信息到服务器上去。那么这时候就存在一个漏洞了。如果你访问了一个恶意网站,这个网站可以在网页源码中插入JS代码,使用JS代码给其他服务器发送请求。因为在发送请求的时候,浏览器会自动把cookie发送给对应的服务器,这时候相应的服务器就不知道这个请求是伪造的。从而达到在用户不知情的情况下,给某个服务器发送了一个请求。

防御CSRF攻击原理
CSRF攻击的要点就是在向服务器发送请求的时候,相应的cookie会自动的发送给对应的服务器。造成服务器不知道这个请求是用户发起的还是伪造的。这时候,我们可以在用户每次访问有表单页面的时候,在网页源码中加一个随机的字符串叫做csrf_token,在cookie中也加入一个相同值的csrf_token字符串。以后给服务器发送请求的时候,必须在body中以及cookie中都携带 csrf_token,服务器只有检测到cookie中的csrf_token和body中的csrf_token都相同,才认为这个请求是正常的。否则就是伪造的,那么黑客就没办法伪造请求了。
Flask防御CSRF攻击
使用flask_wtf.CSRFProtect来包裹app
import os
from flask_wtf import CSRFProtect
app.config['SECRET_KEY'] = os.urandom(24) #和session一样,必须要配置一个secret key参与加密
CSRFProtect(app)
然后在模板form表单中添加一个input标签,加载csrf_token
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
以上配置就能够在,用户在提交表单后一并把表单中的csrf_token提交到服务器,并和服务器上的csrf_token做对比,这样就能够识别请求是否是伪造的,从而避免CSRF攻击
AJAX处理CSRF漏洞
如果我们的表单是通过AJAX提交处理的。示例如下
<head>
...
<!--我们这里的AJAX代码是用JQuery写的,因此要引入Jquery-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<!--AJAX代码在login.js文件中-->
<script src="{{ url_for('static', filename='login.js') }}"></script>
</head> <body>
<form action="" method="post">
<table>
<tr>
<td>邮箱:</td>
<td><input name="email" type="text" /></td>
</tr> <tr>
<td>密码:</td>
<td><input name="password" type="text" /></td>
</tr> <tr>
<td></td>
<td><input type="submit" value="提交" id="submit"/></td>
</tr>
</table>
</form>
</body>
login.html
login.js

... class LoginView(views.MethodView):
def get(self):
return render_template('login.html') def post(self):
email = request.form.get('email')
password = request.form.get('password')
if email == 'heboan@qq.com' and password == '':
return '登录成功'
else:
return '登录失败' app.add_url_rule('/login/', view_func=LoginView.as_view('login'))
login视图


以上我们已经成功使用了AJAX处理表单。现在我们启用CSRF,主程序中代码如下:
import os
from flask_wtf import CSRFProtect
app.config['SECRET_KEY'] = os.urandom(24) #和session一样,必须要配置一个secret key参与加密
CSRFProtect(app)
然后我们再次用正确的账号密码登录,发现出现错误,因为我们启用防csrf攻击,但是AJAX那里并没有携带csrf_token,所以请求失败

因此,我们需要在login.html中添加一个表单用来存放token
<form action="" method="post">
<!--添加一个隐藏input用来放置csrf_token-->
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<table>
<tr>
<td>邮箱:</td>
<td><input name="email" type="text" /></td>
</tr> <tr>
<td>密码:</td>
<td><input name="password" type="text" /></td>
</tr> <tr>
<td></td>
<td><input type="submit" value="提交" id="submit"/></td>
</tr>
</table>
</form>
编辑AJAX代码段,把表单中的csrf_token传给服务器作比对

再次登录(强制刷新浏览器,因为js有缓存)

AJAX处理CSRF漏洞--优化代码
csrf_token可以放置的head中。在实际项目中,我们一般也是放在头部,这样做有个好处就是:当多处需要用到csrf_token,我们就不需要多次写一个隐藏的csrf_token表单。特别是在模板继承的时候,我们只要在父模板中的head中加入csrf配置,其子模板就可以直接继承了。
编辑login.html
<head>
<!--在head中加上此配置-->
<meta name="csrf-token" content="{{ csrf_token() }}">
...
</head> <!--表单中就不需要添加一个csrf_token表单了-->
<form action="" method="post">
<table>
<tr>
<td>邮箱:</td>
<td><input name="email" type="text" /></td>
</tr> <tr>
<td>密码:</td>
<td><input name="password" type="text" /></td>
</tr> <tr>
<td></td>
<td><input type="submit" value="提交" id="submit"/></td>
</tr>
</table>
</form>
新建一个heboan_ajax.js, 来封装

修改login.js

最后在login.html中要引入封装的js
<head>
...
<meta name="csrf_token" content="{{ csrf_token() }}">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="{{ url_for('static', filename='heboan_ajax.js') }}"></script>
<script src="{{ url_for('static', filename='login.js') }}"></script> </head>
这样实现的好处就是以后在其他地方处理CSRF的时候,我们直接把我们封装好的heboan_ajax拿来用就可以了,模板那边可以通过继承实现避免重复定义csrf_token表单和js引入
19、Flask实战第19天:CSRF攻击与防御的更多相关文章
- ARP缓存表的构成ARP协议全面实战协议详解、攻击与防御
ARP缓存表的构成ARP协议全面实战协议详解.攻击与防御 1.4.3 ARP缓存表的构成 在局域网的任何一台主机中,都有一个ARP缓存表.该缓存表中保存中多个ARP条目.每个ARP条目都是由一个IP ...
- CSRF——攻击与防御
CSRF——攻击与防御 author: lake2 0x01 什么是CSRF攻击 CSRF是Cross Site Request Forgery的缩写(也缩写为XSRF),直译过来就是跨站请求伪造的意 ...
- csrf 攻击和防御
CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你的名义发送恶 ...
- CSRF攻击与防御(写得非常好)
转自:http://blog.csdn.net/stpeace/article/details/53512283 CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forge ...
- Web安全之CSRF攻击的防御措施
Web安全之CSRF攻击的防御措施 CSRF是什么? Cross Site Request Forgery,中文是:跨站点请求伪造. CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击 ...
- 转!!CSRF攻击与防御(写得非常好)
CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你的名义发送恶 ...
- csrf 攻击及防御
1.什么是CSRF攻击: CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:C ...
- CSRF攻击与防御(转)
CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你的名义发送 ...
- CSRF攻击与防御
CSRF是什么 CSRF在百度百科中是这么说的:“CSRF(Cross-site request forgery跨站请求伪造,也被称为“one click attack”或者session ridin ...
随机推荐
- [ZJOI2005]沼泽鳄鱼 矩阵乘法
---题面--- 题解: 乍一看还是挺懵逼的.和HH去散步很像,思路也是类似的. 复制一段我在HH去散步的题解里面写的一段话吧: 考虑f[i][j]表示i和j是否右边相连,有为1,否则为0,那么f同时 ...
- [Leetcode] Unique binary search trees ii 唯一二叉搜索树
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...
- BZOJ4008 [HNOI2015]亚瑟王 【概率dp】
题目链接 BZOJ4008 题解 要求所有牌造成伤害的期望,就是求每一张牌发动的概率\(g[i]\) 我们发现一张牌能否发动,还与其前面的牌是否发动有关 那我们设\(f[i][j]\)表示前\(i\) ...
- Tumblr:150亿月浏览量背后的架构挑战
Tumblr:150亿月浏览量背后的架构挑战 2013/04/08 · IT技术, 开发 · 9.9K 阅读 · HBase, Tumblr, 架构 英文原文:High Scalability,编译: ...
- 学习python类
类:Python 类提供了面向对象编程的所有基本特征: 允许多继承的类继承机制, 派生类可以重写它父类的任何方法, 一个方法可以调用父类中重名的方法. 对象可以包含任意数量和类型的数据成员. 作为模块 ...
- nginx,docker反向代理
1. [root@javanginx ~]# cat /etc/nginx/nginx.conf user root root;worker_processes 4;error_log /var/lo ...
- [洛谷P3501] [POI2010]ANT-Antisymmetry
洛谷题目链接:[POI2010]ANT-Antisymmetry 题目描述 Byteasar studies certain strings of zeroes and ones. Let be su ...
- [Codevs1519]过路费解题报告|最小生成树|LCA
在某个遥远的国家里,有 n个城市.编号为 1,2,3,…,n.这个国家的政府修建了m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市T需要收取的过路费为所经过城市之间道路长度的最大值. ...
- CentOS 7 主机加固手册-上
TIPs: 世界上有一撮人专门研究主机安全加固基线,有兴趣的读者可以到 http://benchmarks.cisecurity.org/ 获取更加详细专业的主机安全基线配置文档.或者到 https: ...
- UVa 12265 贩卖土地 单调栈
题意 输入一个\(n\times m\)的矩阵,每个格子可能是空地,也可能是沼泽.对于每个空地格子,求出以它为右下角的空矩形的最大周长,然后统计每个周长出现了多少次. 思路 对于 每一行 每两个沼泽之 ...