Flask使用token来防御csrf跨站攻击

做pytoner工程师很多时候也是需要写web的。 那么你已经会碰到被攻击的危险。比如Csrf攻击,那么csrf是什么我这里就不再详细的描述,我想大家也应该知道。 Flask本身提供了插件,一些社区也在简单的token之上又做了一些关于csrf的防御。



图中Browse是浏览器,WebServerA是受信任网站/被攻击网站A,WebServerB是恶意网站/攻击网站B。
(1),一开始用户打开浏览器,访问受信任网站A,输入用户名和密码登陆请求登陆网站A。
(2),网站A验证用户信息,用户信息通过验证后,网站A产生Cookie信息并返回给浏览器。
(3),用户登陆网站A成功后,可以正常请求网站A。
(4),用户未退出网站A之前,在同一浏览器中,打开一个TAB访问网站B。
(5),网站B看到有人方式后,他会返回一些攻击性代码。
(6),浏览器在接受到这些攻击性代码后,促使用户不知情的情况下浏览器携带Cookie(包括sessionId)信息,请求网站A。这种请求有可能更新密码,添加用户什么的操作。

从上面CSRF攻击原理可以看出,要完成一次CSRF攻击,需要被攻击者完成两个步骤:
1, 登陆受信任网站A,并在本地生成COOKIE。
2, 在不登出A的情况下,访问危险网站 B。
看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:
1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了……)
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。


现在常见的csrf防御是有那么几种方式,一种是在表单加上随机token串,一种是附加token的基础上加了refer的来源判断,还有一种是XMLHttpRequest的请求的方式,他可以不用在表单里面加header,但是问题来了,如果你的网站以前经常用的时动态加载的数据,也就是ajax方式加载的,那么很容易用XMLHttpRequest在请求体里面加上先前respone返回token,也有一些超级笨蛋的方法,那就是加验证码,我相信这方法在一个网站不可能每个表单都有,那这样会让人疯掉的。 

最近有好几个网站爬虫行为不轨,这里标记下我的博客,http://xiaorui.cc

http://xiaorui.cc




有朋友用过Django和tornado,他们可以简单的开启csrf防御,实现的方法大同小异,区别就在于封装的程度,后期加入csrf对于项目来说变动大不大而已… … 

正体:

@app.before_request
def csrf_protect():
    if request.method == "POST":
        token = session.pop('_csrf_token', None)
        if not token or token != request.form.get('_csrf_token'):
            abort(403)

def generate_csrf_token():
    if '_csrf_token' not in session:
        session['_csrf_token'] = some_random_string()
    return session['_csrf_token']

在flask的全局变量里面注册 上面那个生成随机token的函数

app.jinja_env.globals['csrf_token'] = generate_csrf_token        

在网页的模板是这么引入的  ~

<form method=post action="">
    <input name=_csrf_token type=hidden value="{{ csrf_token() }}">

明天还要上班,文章就先写到这里, 明天继续更新关于python防御csrf的方式…


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

2 Responses

  1. 半人间1895 2015年4月30日 / 上午10:07

    好文。最近在看tornado的源码, 看的也是晕晕的。 IOloop IOstream 看着那么别扭。

  2. Leon 2015年1月21日 / 上午11:13

    哇哈哈 大神多讲些Flask的内容哈。。。最近在学习

发表评论

邮箱地址不会被公开。 必填项已用*标注