零、基本信息

CVE-ID:CVE-2018-14574
漏洞类型:URL跳转
影响范围:1.11.0 <= version < 1.11.15 和 2.0.0 <= version < 2.0.8

一、环境复现

二、漏洞分析

当setting中配置了django.middleware.common.CommonMiddleware且APPEND_SLASH为True时漏洞就会触发,而这两个配置时默认存在的,而且APPEND_SLASH不用显示写在setting文件中的。CommonMiddleware是Django中一个通用中间件,实质上是一个类,位于site-packages/django/middleware/common.py,会执行一些HTTP请求的基础操作:

- Forbid access to User-Agents in settings.DISALLOWED_USER_AGENTS

- URL rewriting: Based on the APPEND_SLASH and PREPEND_WWW settings,
append missing slashes and/or prepends missing "www."s.

  - If APPEND_SLASH is set and the initial URL doesn't end with a
    slash, and it is not found in urlpatterns, form a new URL by
    appending a slash at the end. If this new URL is found in
    urlpatterns, return an HTTP redirect to this new URL; otherwise
    process the initial URL as usual.

This behavior can be customized by subclassing CommonMiddleware and
overriding the response_redirect_class attribute.

- ETags: If the USE_ETAGS setting is set, ETags will be calculated from
the entire page content and Not Modified responses will be returned
appropriately. USE_ETAGS is deprecated in favor of
ConditionalGetMiddleware.

而漏洞就与URL rewriting有关:如果设置了APPEND_SLASH=True并且初始URL没有以斜杠结尾,并且在urlpatterns中找不到它,则通过在末尾附加斜杠来形成新的URL。如果在urlpatterns中找到此新URL,则将HTTP重定向返回到此新URL。换句话说就是对那些末尾没加/的url自动填补/然后重新发起请求。比如

但是当发起当发起类似这样的请求http://127.0.0.1:8000//baidu.com 程序就会进行设定的跳转,首先会执行process_request()函数,在61行进入get_full_path_with_slash()函数

这个函数的作用就是get_full_path()函数给path末尾加上斜杠

返回的new_path就是//baidu.com/ ,然后在68行进入HttpResponseRedirectBase这个类,它是HTTP跳转的一个基类

虽然类的初始化函数里(409行)有对协议的检查,但是scheme根本就不存在,所以会跳过这个判断。

在往后就是正常的301跳转

双斜线是为了告诉浏览器这是绝对路径,否则就会跳转到http://127.0.0.1:8000/baidu.com/ 而不是baidu了。

三、补丁分析

修补方法就是加了一个编码函数,

对第二个/编码,这样就构不成绝对路径了

四、参考文献

https://nvd.nist.gov/vuln/detail?vulnId=2018-14574
https://github.com/django/django/commit/6fffc3c6d420e44f4029d5643f38d00a39b08525#diff-1f8be0eae49a1bf37d52829eaeda6a4eR14

源链接

Hacking more

...