Django的CSRF原来形同虚设呀⋯⋯

在搞Django 1.3和Uploadify的整合时,被莫名其妙的302困扰,在苦思之后突然发现,原来Uploadify发送请求时是不会发送Cookie信息的。火急火燎地弄了个middleware来将POST中对应字段写到request.COOKIES去。这样一搞,302倒是ok了,但403倒跑了出来。使用抽插,哦不,抽查法找到是Csrf的验证问题,于是天真地把csrfmiddlewaretoken塞到POST里,可是403依旧。甚是火大。

只好乖乖地看源码,看看Django是如何做CSRF验证的。Django是在CsrfViewMiddleware中进行的相关验证,验证过程很简单,从Cookie中拿出token,然后从POST中拿出csrfmiddlewaretoken,然后块俩做一个字符匹配,就哦了。于是明白了,不就再传个cookie嘛,但突然一想,不对呀,csrfmiddlewaretoken的值就是从cookie里拿的,再传同一个值来做验证,这不是和没验证没啥区别么……

于是做了一个试验,结果确实如此,这下Django悲剧了……

实验项目可以在这个地址下载,运行runserver后,用curl来验证

直接GET,无障碍

curl http://127.0.0.1:8000

强制GET,无障碍

curl -G -d test=test http://127.0.0.1:8000

POST,403了,ms没问题?

curl -d test=test http://127.0.0.1:8000

POST,随便加上csrf,靠!!居然过了!!!

curl -d "test=test;csrfmiddlewaretoken=1" -b csrftoken=1  http://127.0.0.1:8000

归根结底,还是这个验证方法有问题,起码post中的token和cookie中的token是用secret_key做过变幻的,这样才能避免伪造,否则,神马都是浮云~~ 望天

P.S. 报bug去了,#15845。不知他们会采用我说的方法不⋯⋯

Updated: 呃,仔细研究以后才发现一开始并没有理解 CRSF 究竟是为了防什么,乌龙了一把,咳咳咳……

对“Django的CSRF原来形同虚设呀⋯⋯”的11条评论

  1. Avatar

    原来是curl惹得祸

  2. Avatar

    好吧,这其实不是CSRF的问题,但暴露了一种攻击方式,嗯

  3. Avatar

    我也遇到这个问题了!

  4. Avatar

    目前暂时用GET ,后端处理def 加上 装饰器@csrf_exempt。

    展开回复(1)

    收起回复

  5. Avatar
    回复:2goo: 目前暂时用GET ,后端处理def 加上 装饰器@csrf_exempt。

    CsrfViewMiddleware是不会检查GET的,所以没必要用csrf_exempt,两者用其一就行。

  6. Avatar

    Jay一直关注你的博客, 能否放个友情链接,谢谢! 我的博客:http://2goo.info

  7. Avatar
  8. Avatar
    回复:2goo: 谢谢了!

    客气 :)

  9. Avatar

    博主你理解错了,CSRF解决的不是灌水机、Bot之类的问题,CSRF主要是为了防止跨站请求。

    因为HTTP请求默认都会带上Cookie,所以攻击者可以在自己的网站上创建一个隐藏的表单并且用JS偷偷提交,而这个偷偷提交的请求是自动带有被攻击站点有效Cookie的。

    但是如果在Cookie里加一个每次登录都改变的csrf,并且在表单里加一个hidden域,提交时验证两者是否匹配,那么以上攻击就没法实现了,因为恶意网站无法读取你的Cookie(因为浏览器的同源策略),所以无法获得Cookie里的CSRF Token,无法伪造出csrf,POST就会失败,这样就不会产生安全问题。

    如果还不懂的话,建议博主仔细研究一下csrf是什么意思。

    展开回复(2)

    收起回复

  10. Avatar
  11. Avatar