6 октября 2026 года команда Django одновременно выпустила версии 6.1.2, 6.0.9 и 5.2.18 с исправлениями четырёх уязвимостей: одной низкой и трёх умеренной степени опасности. Среди затронутых механизмов оказались обработка HTTP-заголовков, пространственные запросы GeoDjango, model formsets и кеширование языковых кодов, а Django 6.1.2 получила ещё несколько отдельных исправлений ORM, admin и работы с базами данных.

Четыре CVE затронули сразу все поддерживаемые ветки Django
Патч-релизы Django 6.1.2, 6.0.9 и 5.2.18 вышли одновременно, потому что все четыре найденные проблемы затрагивали общие механизмы фреймворка. В официальном бюллетене Django перечислены CVE-2026-77050, CVE-2026-84429, CVE-2026-87890 и CVE-2026-87975. Одна уязвимость получила уровень low, ещё три — moderate.
Для разработчиков здесь есть характерная деталь: две проблемы связаны с потенциальным отказом в обслуживании, одна затрагивает GeoDjango и способна инициировать сетевые запросы от имени процесса приложения, ещё одна позволяет злоупотреблять правами через специально сформированные данные model formsets.
Команда Django выпустила исправления для веток 6.1, 6.0 и 5.2 одновременно. В официальном сообщении разработчики проекта отдельно призвали пользователей этих веток перейти на новые патч-релизы как можно скорее.
| Уязвимость | Затронутый механизм | Уровень |
| CVE-2026-77050 | get_supported_language_variant() | Low |
| CVE-2026-84429 | разбор HTTP-заголовков | Moderate |
| CVE-2026-87890 | пространственные запросы GeoDjango | Moderate |
| CVE-2026-87975 | model formsets с редактируемым первичным ключом | Moderate |
Длинные языковые коды могли расходовать память процесса
CVE-2026-77050 обнаружили в django.utils.translation.get_supported_language_variant(). Функция использует внутренний кеш при поиске поддерживаемого варианта языка. Проблема возникала, когда приложение получало большое количество различных и очень длинных языковых кодов.
До исправления такие строки могли становиться ключами кеша раньше, чем Django ограничивал их длину. При достаточно большом потоке уникальных значений память процесса постепенно расходовалась на кеш, создавая сценарий отказа в обслуживании.
В новых версиях Django языковые коды длиннее 500 символов отбрасываются или сокращаются до выполнения кешируемого поиска. Django Security Team оценила эту проблему как уязвимость низкой степени опасности.
Разбор Accept и Content-Type получил защиту от квадратичной нагрузки
CVE-2026-84429 связана с функцией django.utils.http.parse_header_parameters(). При обработке значения с большим количеством разделителей внутри параметра в кавычках время выполнения могло расти квадратично относительно размера входных данных.
Практический сценарий выглядит неприятнее сухого описания алгоритма. До уязвимого кода можно было добраться через HTTP-заголовки Accept или Content-Type, в том числе через механизм согласования типа ответа в HttpRequest.accepts(). Для такого запроса аутентификация не требовалась.
Django сменил внутренний механизм разбора: parse_header_parameters() теперь использует email.message.Message из стандартной библиотеки Python. Из-за этого некоторые необычные или некорректные значения заголовков могут разбираться иначе. В документации приведён пример с RFC 2231 — параметры с отсутствующей кодировкой теперь могут декодироваться по другому пути.
Уязвимость получила уровень moderate.
GeoDjango снова закрыл обход августовской защиты растров
CVE-2026-87890 продолжает историю августовской CVE-2026-15307. Тогда Django ограничил опасные варианты пространственных lookup-запросов, которые могли заставить GDAL работать с внешними источниками. Октябрьская проверка показала ещё один обход через значения типа bytes.
GeoDjango принимал растровые данные в виде байтов без обязательного явного оборачивания в django.contrib.gis.gdal.GDALRaster. Если внутри находился документ VRT со ссылкой на внешний растровый источник, библиотека GDAL могла отправить сетевой запрос от имени процесса Django во время подготовки lookup.
Такой сценарий требовал, чтобы приложение напрямую передавало контролируемые атакующим байтовые данные в пространственный lookup. После обновления растровые значения типа bytes должны быть явно обёрнуты в GDALRaster. Валидные шестнадцатеричные представления геометрий по-прежнему принимаются.
Разработчики Django прямо пометили изменение как обратно несовместимое. Причина здесь связана с закрытием уязвимости, поэтому прежний способ передачи некоторых растровых значений больше не поддерживается.
Эта CVE получила уровень moderate.
Подделанный POST мог выйти за границы queryset в model formsets
CVE-2026-87975 затрагивает model formsets, если первичный ключ модели можно задавать через форму. Специально сформированные POST-данные позволяли удалить объект за пределами ограничивающего queryset либо создать объект через formset, работающий в режиме edit-only.
Проблема проявлялась в конфигурациях, где первичным ключом служит OneToOneField, parent link в inline formset, естественный ключ или UUID, если такой ключ включён в поля формы.
Модели со стандартным BigAutoField в качестве первичного ключа этой уязвимостью не затронуты. Для большинства типовых моделей Django это заметно сужает область атаки, но проекты с кастомными ключами и сложными inline-формами попадают в отдельную категорию риска.
Django классифицировал CVE-2026-87975 как moderate.
Патчи исправили ещё два старых сбоя GeoDjango и ORM
Во всех трёх релизах разработчики доработали ограничитель глубины для вложенных коллекций геометрий. Предыдущая защита от CVE-2026-15830 допускала класс обходов, при котором глубоко вложенные WKB- и WKT-структуры могли обрабатываться некорректно. Новый алгоритм согласует обработку WKB и WKT и одновременно устраняет редкий случай ошибочного отклонения валидной геометрии.
Ещё одно исправление связано с потерей данных в GeoDjango. Ошибка существовала начиная с Django 4.0: при закрытии сетевого растра GeoDjango мог удалить связанный с ним ресурс. Патч для поддерживаемых веток устраняет такое поведение.
У Django 6.1.2 список шире. В этой версии закрыт бесконечный цикл в tuple lookups, например TupleIn, когда слева использовалось выражение F(). Ошибка появилась ещё в ветке 5.2 и могла приводить к зависанию запроса.
Django 6.1.2 отдельно исправила ORM, Oracle, admin и FETCH_PEERS
Текущая ветка 6.1 остаётся на основном этапе поддержки, поэтому Django 6.1.2 получила набор обычных bugfix-патчей поверх общих исправлений безопасности.
В GeoDjango исправлена ситуация с полем, ошибочно настроенным как srid=None: на некоторых базах данных сохранение пространственного значения могло тихо записать NULL вместо генерации ошибки.
Для GeneratedField исправили системную проверку fields.W225, которая ошибочно сообщала, что параметр null не влияет на поле.
На Oracle функция UUID4 могла сохранять UUID в верхнем регистре. После исправления новые значения записываются в нижнем регистре. В release notes разработчики отдельно указывают, что ранее сохранённые значения верхнего регистра способны влиять на корректность последующих запросов.
В Django admin параметр delete_confirmation_max_display=0 теперь действительно скрывает объекты в сообщениях об ошибках inline-форм и на страницах подтверждения удаления.
Механизм FETCH_PEERS, появившийся в Django 6.1 для управления ленивой загрузкой полей модели, раньше не объединял в пакет экземпляры, полученные через select_related(). Из-за этого ORM выполняла лишние запросы. Django 6.1.2 исправляет такое поведение.
Ещё несколько изменений касаются переименования permissions при цепочке RenameModel, лишнего пустого breadcrumb в admindocs и lookup JSONField через Value на СУБД без нативной поддержки JSON.
Разница между 6.1.2, 6.0.9 и 5.2.18 связана со стадией поддержки
Django 6.1 вышел 5 августа 2026 года и остаётся текущей feature-веткой. Основная поддержка этой серии запланирована до апреля 2027 года, расширенная — до декабря 2027-го. Поэтому в 6.1.2 вошли как security-патчи, так и обычные исправления регрессий и ошибок.
Django 6.0 завершил основную поддержку после выхода 6.1. Серия продолжает получать исправления безопасности и потери данных до апреля 2027 года. Django 5.2 имеет статус LTS и находится на расширенной поддержке до апреля 2028 года.
Этим объясняется различие release notes: 6.0.9 и 5.2.18 сосредоточены на четырёх CVE, доработке защиты от глубоко вложенных геометрий и исправлении потери данных в GeoDjango, тогда как 6.1.2 содержит дополнительные исправления текущей ветки.
Октябрьский релиз показывает сразу две повторные доработки защитных механизмов
Самая заметная деталь выпуска связана с двумя исправлениями, которые возвращаются к уже закрывавшимся проблемам. CVE-2026-87890 устраняет вариант обхода августовского патча для пространственных lookup-запросов, а обновлённый ограничитель глубины геометрий исправляет недостатки защиты от CVE-2026-15830.
В результате Django 6.1.2, 6.0.9 и 5.2.18 синхронизируют защиту трёх поддерживаемых веток по четырём новым CVE. При этом Django 6.1.2 заметно отличается объёмом сопутствующих bugfix-изменений, поскольку эта серия всё ещё получает обычные исправления в рамках основной поддержки.
Следующий вопрос касается совместимости проектов, которые передавали растры как bytes: после CVE-2026-87890 такой путь изменён намеренно и помечен разработчиками Django как обратно несовместимый. Насколько часто этот сценарий встречается в реальных GeoDjango-проектах, официальная публикация не оценивает.