CVE-2016-7401-Django CSRF防御绕过漏洞分析

CVE-2016-7401-Django CSRF防御绕过漏洞分析

前言


Django于昨天修复了这个漏洞: https://www.djangoproject.com/weblog/2016/sep/26/security-releases/

其实去年就有类似的问题,报告给Twitter( https://hackerone.com/reports/14883 ),漏洞是由以下几个部分组成的。

0x01 由Google Analytics导致的Cookie注入漏洞

Google Analytics会设置如下的Cookie来追踪用户:

__utmz=123456.123456789.11.2.utmcsr=[HOST]|utmccn=(referral)|utmcmd=referral|utmcct=[PATH]

比如:

__utmz=123456.123456789.11.2.utmcsr=blackfan.ru|utmccn=(referral)|utmcmd=referral|utmcct=/path/

也就是说,我们可以通过控制[PATH]位置来控制一部分Cookie,而且[PATH]位置并没有进行编码和过滤。这也是造成后面漏洞的导火索。

0x02 Django的解析缺陷
不同Web server对Cookie头有不同的解析方式。
通常浏览器发送的Cookie是这样:

Cookie: param1=value1; param2=value2;

很多Web server也接受以“逗号”为分隔符的Cookie头:

Cookie: param1=value1; param2=value2;

Python + Django却因为错误的正则,导致可以使用]作为分隔符:

Cookie: param1=value1; param2=value2;

这个问题是Python原生Cookie库的问题,我们可以在命令行下测试一下:

>>> import Cookie
>>> C = Cookie.SimpleCookie()
>>> C.load('__utmz=blah]csrftoken=x')
>>> C
<SimpleCookie: __utmz='blah'csrftoken='x'>

可见,当c.load('__utmz=blah]csrftoken=x')后,cookie被错误地解析为两个,一个Cookie[__utmz]=blah,一个csrftoken=x。
0x03 不同浏览器处理Cookie的特性
除了Safari以外,所有浏览器都支持将一些特殊字符(空格、逗号或\)设置为Cookie的值。
Chrome处理Cookie属性的数量有限。比如

Set-Cookie: test=test; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=.google.com; domain=blah.blah.blah.google.com;

的domain将会被认为是.google.com而不是blah.blah.blah.google.com。

发表评论

您必须登录才能发表评论!