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: 呃,一般情况下大约是不会有问题的,因为这只是可以任意伪造csrf_token,但通常还有需要csrf保护的地方也会需要sessionid来作用户验证。这篇的问题就可以暂时忽略了。

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

  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: 谢谢了!

    客气 :)

发表评论

评论备注:

  1. 留言时的头像是Gravatar提供的服务。
  2. By submitting a comment here you grant this site a perpetual license to reproduce your words and name/web site in attribution. So, you don't fully own your words, so to speak.