Django是一个相对来说功能比较全的web框架,当然也提供了一些安全的机制。当然我现在接触Django时间不长,去实战做项目的时间也不长,所以这篇文章会持续更新。
CSRF攻击
参考链接:
http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
https://segmentfault.com/a/1190000007932293
首先,csrf是什么呢?
CSRF(cross-site request forgery),中文名叫做跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
csrf可以做什么呢?
你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的问题包括:个人隐私泄露以及财产安全。
csrf的攻击过程,举例说明:
- 假设abc用户登录银行的网站进行操作, 同时也访问了攻击者预先设置好的网站.
- abc点击了攻击者网站的某一个链接,这个链接是http://www.bank.com/xxxx指向银行,银行服务器会根据这个链接携带的参数会进行转账操作.
- 银行服务器在执行转账操作之前会进行SESSION验证是否登录, 但是由于abc已经登录了银行网站,攻击者的链接也是www.bank.com.所以攻击的链接就会携带session id到银行服务器.
- 由于session id是正确的,所以银行会判断操作是由本人发起的,执行转账操作.
演示一下:
根据上面的说明,我们来模拟一下攻击的过程.
- 有www.bank.com跟www.hacker.com.用户abc登录www.bank.com网站之后点击了www.hacker.com的点击抽大奖的诱骗链接
- 此链接会向www.bank.com发起一个post请求.由于请求域名为www.bank.com,所以请求会携带www.bank.com的session id.
下面是www.hacker.com的代码:
可以发现,www.hacker.com的网页中包含了一个向www.bank.com发起的post请求.并且表单都没隐藏了,只有一个诱骗用户点击的按钮.
完整的实例,详见github:https://github.com/chenjiayao/example/tree/master/csrf
预防办法
知道了CSRF攻击是怎样操作的,那么该怎么去预防这种攻击呢?目前有两种方法:
referer 验证
根据HTTP协议,在http请求头中包含一个referer的字段,这个字段记录了该http请求的原地址。通常情况下,执行转账操作的post请求 www.bank.com/transfer.php应该是点击www.bank.com 网页的按钮来触发的操作,这个时候转账请求的referer应该是www.bank.com.而如果黑客要进行csrf攻击,只能在自己的网站www.hacker.com上伪造请求.伪造请求的referer是www.hacker.com.所以我们通过对比post请求的referer是不是www.bank.com就可以判断请求是否合法.
这种方式验证比较简单,网站开发者只要在post请求之前检查referer就可以,但是由于referer是由浏览器提供的.虽然http协议有要求不能篡改referer的值.但是一个网站的安全性绝对不能交由其他人员来保证.
token验证
从上面的样式可以发现,攻击者伪造了转账的表单,那么网站可以在表单中加入了一个随机的token来验证.token随着其他请求数据一起被提交到服务器.服务器通过验证token的值来判断post请求是否合法.由于攻击者没有办法获取到页面信息,所以它没有办法知道token的值.那么伪造的表单中就没有该token值.服务器就可以判断出这个请求是伪造的.
在实战中我使用的随机的 csrftoken 方法,这是Django自带的一种安全机制,并不是任何一个post请求都能被响应,必须跟随的csrftoken也符合条件,这样才能成功响应。
具体的方法是在前端的界面中我们在每个form的结构中的结束符/之前添加变量
举个例子,这是忘记密码界面的form表单:
添加之后呢,在前端界面上会自动的随机生成一个token,代码如下:
把细节拉出来:
这是系统自动生成的两个hidden类型的input,用户在提交post请求将表单内容提交给后端的时候,服务器会验证csrftoken,只有在验证成功之后才能成功提交,因为攻击者不知道表单提交的时候的csrftoken,可以有效的预防。