漏洞原理 若Django项目使用Postgres作为数据库,当触发异常时,psycopg会将字段名及字段值抛出,当字段值中包含可控字符串时,其最后便会在页面中进行显示。
我们可查看1.11.4和1.11.5版本之间django/views/templates/technical_500.html文件的差异:
其差异在于外部关闭了全局转义,并在如图所示处增加了强制转义。若要触发这两个输出点,我们需要进入{% ifchanged frame.exc_cause %}{% if frame.exc_cause %}语句,那么就需要我们判断这段代码所在的功能点,然后精准打击,图中有一串The above exception was the direct cause of the following exception:报错提示,而依据经验的话这是Django中数据库异常抛出的错误语句。
在Django命令行下,当创建一个已存在的用户时,系统会因触发数据库Unique异常而抛出一个IntegrityError异常,其目的在于方便开发者进行SQL错误调试。
查看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....