Если форма отправляется сразу, но после долгого заполнения показывает ошибку, сначала сравните два запроса: отправку сразу после открытия страницы и отправку после паузы. Если отличается только второй сценарий, проверьте срок сессии и соответствие CSRF-токена текущей сессии — но не отключайте защиту ради проверки.
Самый полезный сигнал находится не в тексте всплывающего сообщения, а в запросе на отправку: ушёл ли он вообще, какой HTTP-статус вернул сервер, не было ли перенаправления на вход и присутствовал ли токен в поле или заголовке. Такой порядок быстро отделяет проблему безопасности от ошибки JavaScript, валидации или серверной обработки.
Почему долгая пауза может сломать отправку
CSRF-токен подтверждает, что изменяющий данные запрос пришёл из ожидаемой формы, а не был незаметно инициирован сторонним сайтом. Обычно браузер получает токен вместе со страницей и возвращает его серверу в скрытом поле формы либо в заголовке AJAX-запроса.
Сам по себе токен не обязан иметь отдельный таймер. В конкретном приложении он может быть связан с пользовательской сессией, меняться после повторного входа или становиться недействительным после ротации. Поэтому фраза «истёк CSRF» описывает симптом, но ещё не называет точную причину.
Частые сценарии:
- сессия завершилась, пока человек заполнял форму;
- в другой вкладке пользователь вышел и вошёл снова;
- страница вернулась из кэша браузера со старым токеном;
- HTML формы закэширован на CDN или reverse proxy вместе с пользовательским полем;
- JavaScript отправил запрос, но не добавил актуальный токен;
- запрос остановила клиентская валидация, и до сервера он вообще не дошёл.
Как воспроизвести проблему без догадок
Проверяйте на тестовой записи, чтобы повторная отправка не создала заказ, платёж или заявку реального клиента. Секретные значения токенов и cookies не копируйте в тикет, скриншот или общий чат.
1. Сравните быструю и отложенную отправку
Откройте форму в новой вкладке и отправьте минимально допустимые данные сразу. Затем снова откройте страницу, заполните такую же тестовую форму, дождитесь воспроизведения проблемы и отправьте её.
Если оба варианта падают одинаково, длительность заполнения, скорее всего, ни при чём. Если быстрая отправка успешна, а отложенная нет, зафиксируйте интервал и переходите к проверке сессии, токена и кэша.
2. Посмотрите вкладку Network
До отправки откройте инструменты разработчика, включите сохранение журнала и найдите запрос формы. Зафиксируйте:
- метод и адрес запроса;
- HTTP-статус и цепочку перенаправлений;
- тип данных: обычная форма, JSON или другой формат;
- наличие CSRF-поля или заголовка без публикации его значения;
- короткий безопасный текст ошибки и идентификатор запроса, если он есть.
Если запроса нет, ищите ошибку в консоли, обработчике кнопки или клиентской валидации. Если запрос ушёл и сервер вернул отказ, анализируйте серверную ветку.
3. Отделите завершение сессии от отказа токена
Перенаправление на страницу входа или явный ответ об отсутствии авторизации указывает на завершившуюся сессию. Сообщение о неверном токене при всё ещё активном кабинете чаще говорит о ротации, рассинхронизации вкладок, кэше или ошибке передачи токена.
Код 403 означает, что сервер понял запрос, но отказался его выполнять; он не доказывает проблему именно с CSRF. Некоторые приложения используют для такого отказа другие коды. Смотрите одновременно статус, тело ответа и серверный журнал.
4. Сверьте событие с серверными логами
Ищите запись по времени, маршруту, пользователю и безопасному идентификатору запроса. Полезно увидеть, на каком шаге произошёл отказ: до контроллера, при проверке сессии, при валидации CSRF или уже в бизнес-логике.
Не записывайте в логи полный токен, session cookie, пароль или содержимое чувствительных полей. Для диагностики достаточно типа ошибки и идентификаторов, которые нельзя использовать для входа.
Матрица симптомов
| Симптом | Что проверить первым | | --- | --- | | После обновления страницы форма отправляется | Сессию, ротацию токена и кэш HTML | | Ошибка появляется только после повторного входа в другой вкладке | Привязку токена к новой сессии | | Кнопка нажимается, но запроса нет | JavaScript и клиентскую валидацию | | Запрос есть, токена в нём нет | Сборку формы или AJAX-заголовок | | Ответ успешный, но данные не появились | Серверную логику, БД и интеграции | | Сбой только у одного браузера | Кэш, service worker и расширения |
Эта таблица задаёт порядок проверки, но не заменяет воспроизведение. Одинаковое сообщение интерфейса может скрывать разные ответы сервера.
Что исправить на стороне приложения
Согласовать время жизни
Срок сессии должен учитывать реальное время заполнения формы. Просто сделать сессию бессрочной — плохая замена диагностике: это меняет риск безопасности и не устраняет кэширование старой страницы или ошибку JavaScript.
Не кэшировать пользовательский токен как общий HTML
Если форма персонализирована, нельзя раздавать один закэшированный токен разным пользователям. При полноэкранном кэшировании безопаснее получать пользовательский фрагмент или токен отдельным некэшируемым запросом согласно возможностям выбранного фреймворка.
Дать пользователю восстановимый сценарий
Приложение может заранее предупредить о завершении сессии, предложить обновить форму и сохранить несекретный черновик. Если поля содержат персональные или платёжные данные, способ временного хранения нужно отдельно проверить по требованиям безопасности: бездумно складывать всё в localStorage нельзя.
Сделать ошибку различимой
Пользователю достаточно понятного действия: обновить сессию и повторить отправку без потери безопасных полей. Разработчику нужен отдельный тип события и идентификатор для журнала, но не внутренние детали защиты в публичном сообщении.
Добавить регрессионные проверки
Проверьте быструю и отложенную отправку, две вкладки, повторный вход, кнопку «Назад», мобильный браузер и AJAX-вариант. Для изменяющего данные запроса тест должен исключать незаметный повтор: автоматическая повторная отправка может создать дубль.
Чего не стоит делать
Не отключайте CSRF-проверку и не принимайте любой старый токен. Не лечите симптом только увеличением срока сессии. Не передавайте токены через URL и не публикуйте их в логах. Наконец, не считайте обычную доступность страницы доказательством работы формы: HTTP-ответ главной страницы не воспроизводит длительное заполнение и защищённую отправку.
Web-Puls помогает регулярно проверять доступность публичной страницы и заметить общий сбой, но такой мониторинг не входит в кабинет пользователя и не отправляет реальные формы. Для этой ошибки нужны безопасное воспроизведение, Network и серверные логи.
Практический следующий шаг
Начните с пары «быстрая отправка — отложенная отправка», сохраните время, HTTP-статус и идентификатор запроса, затем передайте эти данные разработчику без токенов и персональных полей. Если проблему нужно не только зафиксировать, но и разобрать на стороне сайта, отправьте заявку на профессиональную поддержку с адресом страницы, временем и описанием двух сценариев.