漏洞分析丨CVE-2020-7471

众所周知,Django是一款开源的Web应用框架,基于MVT模式。PostgreSQL是基于对象的关系型开源数据库,即存在关系型数据库的特点,也具备NoSQL的特征。在Django的官方文档中也力推用户使用PostgreSQL来构建自己的WEB应用。近期,Django官网发布了有关StringAgg方法的SQL注入漏洞(CVE-2020-7471)的修复代码。

作为一名安全开发人员,常年使用Django作为自己的脚手架,认为软件应用程序的安全性为重中之重,所以,进行本次漏洞分析。

Django漏洞公告(图片来源:Django官网)

首先,先讲解有关本次漏洞的核心知识点,主要有以下两点:

  • PostgreSQL聚合函数string_agg与array_agg函数的使用

  • Django框架annotate函数与aggregates函数的使用

下面,分别进行带入讲解。

string_agg与array_agg

string_agg与array_agg函数的功能都与聚合操作相关,只不过它们合并的数据类型不同。array_agg允许用户输入数值或数组,最终串联为数组,表达式如:array_agg(expression)。

array_agg

而string_agg允许用户输入数值,从而根据自定义分隔符串联成一个字符串,表达式如:string_agg(expression, delimiter)。

string_agg

annotate与aggregates

在我们使用SQL语句查询分析时,经常会使用filter()等较普通的函数,当我们需要进行更高级别的统计操作时,就需要熟练的掌握annotate与aggregates的使用方法。

aggregates是聚合的意思,当你需要对查询集(queryset)的某些字段进行聚合操作时(比如Sum、Avg、Max),请使用aggregate方法。如果你想要对数据集先进行分组(Group By)然后再进行某些聚合操作或排序时,请使用annotate方法。

接下来,在了解了上面的基础知识点后,再来探究Django中StringAgg()函数使用时为什么会出现SQL注入漏洞?我们会从环境搭建到漏洞复现,一步一步为大家展示。

0x00

环境搭建

根据官网提供的漏洞信息可知哪个Django版本存在漏洞。

漏洞影响版本范围(图片来源:Django官网)

首先使用django-admin命令创建测试环境。

创建漏洞环境

使用pip安装psycopg2-binary模块(Django==3.0),再使用宝塔安装PostgreSQL(我认为比较方便一些)。

PostgreSQL安装

安装完成后打开项目进行配置,首先配置连接PostgreSQL数据库。

PostgreSQL连接配置

项目安装成功,启动本次测试环境,开始漏洞复现。

测试环境启动

0x01

漏洞复现

打开app/model.py文件,设置CharField类型username字段。

设置字段

终端执行数据库初始化命令,操作以下命令后,创建数据库完成。

数据库初始化

使用Django shell模式插入测试数据。

插入测试数据

根据官方发布,找到存在漏洞的函数位置,并调用。

调用存在漏洞的函数

通过shell模式调试,如下StringAgg的delimiter参数成功将多条记录按照分号分隔,串联为一个字符串。

调试StringAgg方法

输入单引号将参数闭合,成功报错,发现没有做任何过滤直接带入查询。

测试注入是否存在

将Payload带入测试,存在延迟,复现成功。

POC测试复现

0x02

漏洞原理分析

跟踪进入函数django.contrib.postgres.aggregates.StringAgg。

POC测试复现

可以看到用户自定义的delimiter参数直接被嵌入到表达式中执行,并且无任何后续转义操作,所以导致SQL注入的存在。

0x03

修复建议

根据官方的修复建议将Django版本升级至3.0.3、2.2.10或1.11.28即可。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章