Django debug page XSS漏洞(CVE-2017-12794)分析

Django debug page XSS漏洞(CVE-2017-12794)分析

Django 简介

基本介绍
Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。

使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能的 Web 服务 Django 本身基于 MVC 模型,即 Model(模型)+ View(视图)+ Controller(控制器)设计模式,MVC 模式使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能
Django详情参考菜鸟教程

CVE-2017-12794漏洞分析

漏洞利用版本1.11.4XSS漏洞
请添加图片描述
可见,外部关闭了全局转义,然后在这两个地方增加了强制转义。那么,漏洞肯定是在这个位置触发的。

如果要触发这两个输出点,就必须进入这个if语句:{% ifchanged frame.exc_cause %}{% if frame.exc_cause %}

The above exception was the direct cause of the following exception: 一般是在出现数据库异常的时候,会抛出这样的错误语句。

做个简单的测试,在Django命令行下,我们创建一个username为phith0n的用户,然后再次创建一个username为phith0n的用户,则会抛出一个IntegrityError异常:
请添加图片描述
见上图,原因是触发了数据库的Unique异常。

为什么Django会引入这样一个异常机制?这是为了方便开发者进行SQL错误的调试,因为Django的模型最终是操作数据库,数据库中具体出现什么错误,是Django无法100%预测的。那么,为了方便开发者快速找到是哪个操作触发了数据库异常,就需要将这两个异常回溯栈关联到一块。

我们可以看看代码,django/db/utils.py的__exit__函数:

def __exit__(self, exc_type, exc_value, traceback):
   if exc_type is None:
       return
   for dj_exc_type in (
           DataError,
           OperationalError,
           IntegrityError,
           InternalError,
           ProgrammingError,
           NotSupportedError,
           DatabaseError,
           InterfaceError,
           Error,
   ):
       db_exc_type = getattr(self.wrapper.Database, dj_exc_type.__name__)
       if issubclass(exc_type, db_exc_type):
           dj_exc_value = dj_exc_type(*exc_value.args)
           dj_exc_value.__cause__ = exc_value
           if not hasattr(exc_value, '__traceback__'):
               exc_value.__traceback__ = traceback
           # Only set the 'errors_occurred' flag for errors that may make
           # the connection unusable.
           if dj_exc_type not in (DataError, IntegrityError):
               self.wrapper.errors_occurred = True
           six.reraise(dj_exc_type, dj_exc_value, traceback)

其中exc_type是异常,如果其类型是DataError,OperationalError,IntegrityError,InternalError,ProgrammingError,NotSupportedError,DatabaseError,InterfaceError,Error之一,则抛出一个同类型的新异常,并设置其__cause____traceback__为此时上下文的exc_value和traceback。

exc_value是上一个异常的说明,traceback是上一个异常的回溯栈。这个函数其实就是关联了上一个异常和当前的新异常。

最后,在500页面中,__cause__被输出。

漏洞利用

经过测试,发现在使用Postgres数据库并触发异常的时候,psycopg2会将字段名和字段值全部抛出。那么,如果字段值中包含我们可控的字符串,这个字符串其实就会被设置成__cause__,最后被显示在页面中。

所以我们假设有如下场景:

  1. 用户注册页面,未检查用户名

  2. 注册一个用户名为<script>alert(1)</script>的用户

  3. 再次注册一个用户名为<script>alert(1)</script>的用户

  4. 触发duplicate key异常,导致XSS漏洞

访问http://your-ip:8000/create_user/?username=<script>alert(1)</script>创建一个用户,成功;
请添加图片描述
再次访问http://your-ip:8000/create_user/?username=<script>alert(1)</script>,触发异常:
请添加图片描述
请添加图片描述
可见,Postgres抛出的异常为
duplicate key value violates unique constraint "xss_user_username_key" DETAIL: Key (username)=(<script>alert(1)</script>) already exists.

这个异常被拼接进The above exception ({{ frame.exc_cause }}) was the direct cause of the following exception,最后触发XSS。

摘选自 Vulhub靶详解:Django debug page XSS漏洞(CVE-2017-12794)分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值