Мои проекты

Commentail 1.3.1: защита данных и ограничения форм

В Commentail 1.3.1 я изменил хранение отпечатков для квот и повторных отправок, добавил ограничения выдачи форм и усилил проверку принадлежности страниц сайту. Обновление требует необратимой миграции данных.

Коротко

  • Отпечатки квот и повторных отправок защищены HMAC; действующие квоты и принятые повторы сохраняются.
  • Новые формы ограничены по IP и Site, а просроченные служебные записи удаляются небольшими порциями.
  • Миграция 0018 необратима. Для нового обновления выбирайте 1.3.2: там исправлена ошибка обсуждений в переводах.
Синяя птица Commentail на облачке комментария, версия 1.3.1.
Commentail 1.3.1 — комментарии для Wagtail.

Выпустил Commentail 1.3.1 — обновление защиты комментариев для Wagtail. Здесь несколько изменений, которые затрагивают хранение служебных данных, выдачу форм и доступ к обсуждениям. Возможности самой библиотеки описаны на странице проекта.

Что изменилось в хранении отпечатков

Для подсчёта квот и распознавания повторной отправки Commentail хранит отпечатки идентификаторов и содержимого запроса. Раньше для этих значений использовались обычные SHA-256-хеши. Если исходное значение можно угадать, например перебрать IP-адреса, копия базы позволяет проверять такие догадки.

В 1.3.1 я перевёл эти отпечатки на HMAC с ключом на основе SECRET_KEY Django. Для разных назначений используются отдельные контексты: квоты учитывают сайт и тип события, а отпечаток отправки — конкретное обсуждение. Без ключа одной копии базы недостаточно, чтобы сверять предполагаемые значения с этими отпечатками.

Это не шифрование комментариев или приватных email-полей. Случайные секреты защищённых ссылок, форм и подтверждений браузера сохраняют прежний способ хранения. Уже существовавшая HMAC-проверка повторяющегося гостевого текста тоже не заменяется этим обновлением.

Миграция преобразует старые отпечатки без восстановления исходных данных. Текущие квоты не обнуляются, а повтор принятой отправки продолжает распознаваться. Для последующей смены ключа эти записи поддерживают SECRET_KEY_FALLBACKS; историю совпадений гостевого текста смена ключа начинает заново.

Ограничения выдачи новых форм

Проверять ограничения только при отправке комментария недостаточно для выдачи служебных записей: открытие и восстановление формы тоже создают данные. Теперь выдача новых форм и билетов восстановления ограничена для гостей и вошедших пользователей. В лимит входит и навигация, если она выдаёт новый билет.

По умолчанию на один IP-адрес в пределах одного Site разрешено 120 новых билетов за минуту и 1200 за час. Эти значения задаются параметрами FORM_IP_LIMIT_PER_MINUTE и FORM_IP_LIMIT_PER_HOUR. Это отдельные ограничения: квоты принятых комментариев и гостевых попыток сохраняют своё назначение.

При достижении лимита чтение обсуждения остаётся доступным. Уже выданная действующая форма продолжает работать, а отказ не создаёт ни нового билета, ни CAPTCHA. Введённый текст остаётся в форме ответа с ошибкой. После окончания окна ограничения можно повторить проверку без перезагрузки страницы.

Но новый билет восстановления при отказе не сохраняется. Перед уходом со страницы стоит скопировать набранный текст. Для офиса, учебного заведения или другой общей сети лимиты нужно подобрать по реальному трафику.

Принадлежность страницы сайту

Обсуждение связано с определённым Site. В 1.3.1 добавлена проверка, что целевая страница остаётся внутри его корневого дерева. Она применяется к прямым обращениям, защищённым гостевым ссылкам и письмам в очереди. Если страницу перенесли за пределы разрешённого дерева, прежняя ссылка не должна сохранять доступ к ней.

В этой проверке я допустил ошибку для многоязычных сайтов: переводы главной страницы Wagtail могут находиться в соседних деревьях, которые 1.3.1 считала чужими. В результате корректные обсуждения переводов становились недоступны. Исправление вышло в 1.3.2; ограничения доступа к закрытым и неопубликованным страницам сохранены.

Очистка записей и диагностика адаптеров

Просроченные CAPTCHA, гостевые разрешения, билеты форм и события квот удаляются порциями не более 500 записей. Каждая порция фиксируется в отдельной транзакции. Если следующая завершится с ошибкой, уже выполненная очистка не откатится целиком. Действующие записи сохраняются; расписание существующей фоновой обработки по-прежнему нужно настроить на сайте.

Для адаптеров обычных Django-моделей сообщения об ошибках стали точнее. Отдельно различаются проблемы с разрешением модели, типом первичного ключа, дублирующей регистрацией, импортом класса и обязательными методами. Произвольный текст исключения адаптера при этом не попадает в публичную диагностику.

Как подготовить обновление

Миграция 0018_private_fingerprints меняет данные в одной транзакции и не имеет обратного преобразования. Новых зависимостей и изменений схемы в 1.3.1 нет, но это не делает переход обычной заменой пакета.

Сначала проверьте обновление на восстановленной копии базы. Сохраните вместе базу, SECRET_KEY, настройки, переопределённые шаблоны и точные версии прежнего пакета и зависимостей. При обновлении остановите веб-процессы и фоновые обработчики, которые могут писать в базу. Ключ должен остаться прежним; одновременно запускать старые и новые процессы нельзя. На большой базе нужно предусмотреть время и место для транзакции.

Для перехода сразу на исправленный выпуск, после резервного копирования и остановки записи:

bash
python -m pip install commentail==1.3.2
python manage.py migrate
python manage.py check
python manage.py collectstatic --noinput

Затем перезапустите приложение и фоновые процессы. Проверьте открытую до обновления форму, повтор принятой отправки, гостевые и авторизованные комментарии, ошибки CAPTCHA, восстановление текста, ответы, защищённые ссылки и почту. Если шаблоны форм переопределены, сравните обработку отказа выдачи формы и состояние кнопки отправки с новой версией.

За nginx отдельно проверьте TRUSTED_PROXIES и передачу адреса посетителя. По умолчанию Commentail использует адрес прямого подключения: без корректной настройки все посетители могут делить квоту IP-адреса прокси.

Для отката нужна согласованная копия базы, ключа и прежнего пакета при остановленной записи. Простая переустановка старой версии или обратный запуск миграций данные не восстановят. Старые резервные копии и экспорты также сохраняют прежние хеши и требуют отдельной защиты.

Подробности — в руководстве по миграции и восстановлению и описании защиты и приватности.

Была ли статья полезна?

Комментарии 0

Имя: до 40 символов.

После отправки мы пришлём письмо со ссылкой для подтверждения email.

Не более 5000 символов.

Опубликованных комментариев пока нет.