CSRF攻击与防御(写得非常好)
CSRF
全拼为Cross Site Request Forgery
,翻译过来就是跨站请求伪造
跨站请求伪造(CSRF)是Web应用程序的一种常见的漏洞;其特性是危害性大,并且极其隐蔽。下面就从CSRF的危害实例,攻击原理,防御方法几个方面进行解释说明。
CSRF的危害实例与过程解析
本案例主人公:
用户:xiaoming
A银行网站:www.Abank.com
黑客网站:www.heikebank.com
1.xiaoming 今天闲来无事访问A银行的网站,由于需要查询个人账户的一些信息,所以登陆到A银行的账户上。
在xiaoming登陆了A银行的网站后,发生了下面的几件事:
1.xiaoming将自己的账号(user_id= xiaoming)和自己账号对应的密码(user_pwd=123456)通过请求报文发送给服务器了; 【服务器生成带有cookie的响应报文】 2.服务器收到xiaoming的请求,将他登陆输入的账号和密码与服务器数据库中的数据进行比对,在校验无误后,将登陆成功的数据反馈给浏览器,当然,这个时候,在服务器生成的关于账号和密码的cookie响应给浏览器; 【服务器将响应报文返回给浏览器,浏览器本地保存了有个人信息的cookie】 3.此时,浏览器的cookie是保存了xiaoming个人账号和密码的
2.好的,在xiaoming浏览了一会A银行网站之后,闲暇之余,点开了黑客网站,打开黑客网站之后,有一个非常诱人的【领取优惠券】的点击界面,xiaoming经不住诱惑,点击了这个按钮
1.先看看A网站的转账界面
这个界面的网页源代码如下:
网址为:http://127.0.0.1:9000/transfer
# 这里只展示需要获取提交信息的表单部分的代码: <form method="post"> <label>账户:</label><input type="text" name="to_account" placeholder="请输入对方账户"><br/> <label>金额:</label><input type="number" name="money" placeholder="请输入转账金额"><br/> <input type="submit" value="转账"> </form>
2.再来看一下黑客网站的优惠券页面显示情况:
这里的页面显示,你看到的是别人希望你看到的,然后我们再查阅一下这个显示界面下的网页源代码:
<form method="post" action="http://127.0.0.1:9000/transfer"> <input type="hidden" name="to_account" value="999999"> <input type="hidden" name="money" value="190000"> <input type="submit" value="点击领取优惠券"> </form>
表面上,你是在访问网站B的优惠券领取界面,实际上,这个界面的访问地址是:http://127.0.0.1:9000/transfer
也就是说,我们看到的是点击获取优惠券,但是实际上,我们在底层实现的是,访问了A网站的转账页面,并且将转账的金额和转账的对象通过隐藏,让xiaoming无法看到。
CSRF防御 - - -(请求地址中添加 token):
上面的案例发生的前提是:xiaoming在访问黑客网站时,没有登出网站A,或者说,网站A存在的cookie没有过期,并且可用。
而且,正常情况下,cookie的都不会太快时间过期,也就是说,如果没有好的防御机制,那么我们的账户就很容易被偷袭。
下面来介绍一下,如何进行CSRF的防御:
首先先声明两个代码:
1 # 后端代码增加: 2 app.config['WTF_CSRF_ENABLED'] = True
1 # 前端代码增加 2 {{ form.csrf_token() }}
这两段代码在添加后,实现的功能如下:
1 首先,在app.config['WTF_CSRF_ENABLED'] = True 配置下,在服务端会自动生成一段 随机的csrf_token值;注意:csrf_token值是保存在session中的,所以,需要进行app.secret_key = 'qwertyui'的配置; 2 其次,在返回转账页面的响应里面设置 csrf_token值 到 cookie 中(session依赖cookie进行传递); 3 将 csrf_token 保存到表单的隐藏字段中(表单内容是在本地浏览器界面中的,而且每次刷新的时候,都会更新一个新的csrf_token值;由于隐藏在xiaoming的本地浏览器中,黑客网站是无法获取到的) 4 当需要进行转账操作时,会将之前生成的浏览器中的csrf_token值跟随转账请求一起传送到服务端;服务端除了需要校验cookie中的用户名和密码是否匹配,还需要进行请求中csrf_token值与服务端session中存储的csrf_token是否一致。 5 在所有匹配都符合要求的情况下,才可以进行转账操作。