CVE-2024-42005
Django JSONField: SQL-инъекция при выборе полей
Если приложение Django передаёт недоверенный ключ JSON в values() или values_list(), старые версии могут небезопасно сформировать запрос к базе. Проверьте именно этот путь данных и обновите Django до поддерживаемой исправленной ветки.
Кому нужно проверить
Разработчикам и владельцам сайтов на Django с гибкими фильтрами, отчётами или API, где пользователь выбирает данные из JSON-полей. Владельцу сайта полезно попросить разработчика проверить не только версию, но и происхождение аргументов методов выборки. Важна не только марка продукта, но и конкретная версия, способ установки, операционная система и конфигурация.
В чём риск
База данных принимает запросы на языке SQL. Django обычно составляет их из действий программы, отделяя значения пользователя от команд. В этой ошибке ключ внутри JSON мог попасть в формирование псевдонима столбца — внутреннего имени результата — небезопасным способом. SQL-инъекция означает возможность изменить смысл запроса через данные, которые должны были остаться только данными. Последствия зависят от запроса, базы и полномочий её учётной записи; advisory не подтверждает безусловный доступ ко всем данным или выполнение команд операционной системы. Обычная загрузка JSON без описанного вызова не равнозначна этому сценарию.
Затронутые версии
По записи CVE затронуты Django 4.2 до 4.2.15 и 5.0 до 5.0.8. Условие — методы QuerySet.values() или values_list() на модели с JSONField получают специально сформированный ключ JSON как позиционный аргумент. Advisory также указывал основную ветку разработки и готовившуюся 5.1, находившуюся тогда в статусе release candidate. Наличие JSONField без передачи недоверенных значений в эти методы не доказывает данный путь атаки. Старые неподдерживаемые ветки нельзя объявлять безопасными только потому, что они не перечислены среди поддерживавшихся на момент исправления.
Исправленные версии
Security-релизы от 6 августа 2024 года — Django 4.2.15 и 5.0.8; исправления также внесены в ветки main и 5.1 до окончательного выпуска последней. На дату проверки ветки 4.2 и 5.0 уже не поддерживаются. Для рабочего проекта выбирайте актуальный патч поддерживаемой ветки, совместимой с Python и зависимостями; например, ветка 5.2 LTS указана проектом как поддерживаемая до апреля 2028 года. Проверяйте текущую таблицу поддержки перед миграцией.
Что сделать
- 1Установите версию Django в окружении работающего приложения и в каждом развёрнутом образе. Передайте разработчику список мест использования values() и values_list() с JSONField. Нужно проследить аргументы до источника: параметры запроса, сохранённые настройки пользователя и внешние интеграции также могут быть недоверенными.
- 2Если пользователь выбирает поля, временно ограничьте выбор фиксированным списком, заданным разработчиком, или отключите затронутую функцию. Простого удаления кавычек недостаточно как общего доказательства безопасности. Ограничение функциональности не заменяет обновление Django.
- 3Сохраните зависимости, настройки и проверенную резервную копию базы данных. Подготовьте тестовую среду с обезличенными данными. При переходе с неподдерживаемой ветки проверьте совместимость Python, драйвера базы, расширений и изменения Django между выпусками.
- 4Обновите Django через штатный процесс управления зависимостями проекта и пересоберите все образы. Проверьте обычные отчёты, выбор ключей JSON и ожидаемый отказ для неподдерживаемых названий полей. Рабочие SQL-инъекции и эксперименты на продуктивной базе для этого не нужны.
- 5Если миграция меняет схему базы, заранее согласуйте отдельный план восстановления данных: откат образа приложения не всегда откатывает схему. Разверните обновление в окно обслуживания и перезапустите веб-процессы и фоновые задачи. При возврате к уязвимой версии держите затронутую функцию закрытой.
- 6Подтвердите версию в реально запущенных окружениях, проверьте штатные запросы и ошибки базы. При подозрительных обращениях сопоставьте журналы приложения и базы, не публикуя SQL с пользовательскими данными. Отсутствие ошибок не доказывает, что доступ к данным не происходил.
Граница между выбором поля и изменением SQL
Пользователь или внешний источник задаёт ключ JSON. Исправление Django и ограниченный выбор полей защищают эту границу.
- 1Пользователь или внешний источник задаёт ключ JSON.
- 2Приложение передаёт ключ в values() или values_list().
- 3Уязвимая версия небезопасно формирует псевдоним столбца.
- 4Исправление Django и ограниченный выбор полей защищают эту границу.
Примеры конфигурации и проверки
python -m django --versionТерминал в доверенном окружении проекта с установленным Django и его совместимым Python. Сначала выберите используемое приложением виртуальное окружение или контейнер по инструкции проекта. Запускайте обычной служебной учётной записью без sudo. Ожидается номер Django; ошибка отсутствия модуля означает, что выбранное окружение не содержит Django, а не что сайт безопасен. Команда не выполняет миграции и ничего не меняет, откат не требуется. Она не проверяет передачу аргументов и версию уже запущенных процессов.
Как не подпустить ботов к сайту
BotProtection принимает запросы перед вашим сайтом и фильтрует автоматизированные обращения. Поэтому ботам сложнее добраться до уязвимого компонента и начать его проверять или атаковать, а вероятность успешной автоматизированной атаки становится значительно ниже. Это дополнительный слой защиты: обновление уязвимых компонентов, проверка журналов и реагирование на инциденты остаются обязательными.
Первоисточники
Снизьте шанс атаки до того, как бот дойдёт до сайта
Подключите BotProtection как фильтр перед сайтом: подозрительные автоматизированные запросы отсекаются до обращения к вашему серверу. Это значительно снижает вероятность автоматизированной атаки, но не исправляет саму уязвимость, поэтому обновление и настройка компонентов остаются обязательными.