Неверный csrf токен проверьте включена ли поддержка cookie в веб браузере
Мой код формы таков:
Вам нужно добавить _token в свою форму, т.е.
На данный момент в вашей форме отсутствует поле токена CSRF. Если вы используете функции формы веточки для визуализации вашей формы, например form(form) , это автоматически отобразит для вас поле токена CSRF, но ваш код показывает, что вы визуализируете свою форму с помощью необработанного HTML, например , поэтому у вас чтобы вручную отобразить поле.
Или просто добавьте > перед закрывающим тегом формы.
Согласно документам
Это отображает все поля, которые еще не были отображены для данной формы. Это хорошая идея, чтобы всегда иметь это где-то внутри вашей формы, поскольку он будет отображать скрытые поля для вас и сделает любые поля, которые вы забыли, более очевидными (так как это будет отображать поле для вас).
Эта опция в php.ini вызывает проблему
Проблема в том, что поле _token пропускает запрос PUT (GET), поэтому вам нужно увеличить значение.
Также это касается больших файлов. Увеличение
Вариант решит проблему.
Это происходит потому, что формы по умолчанию содержат защиту CSRF, которая в некоторых случаях не требуется.
Вы можете отключить эту защиту CSRF в своем классе формы в методе getDefaultOptions следующим образом:
Если вы не хотите отключать защиту CSRF, вам необходимо отобразить поле защиты CSRF в вашей форме. Это можно сделать, используя > в вашем файле просмотра, например:
> отображает все поля, которые вы не ввели вручную.
Перед тегом поместите:
Он автоматически вставит другие важные (скрытые) входные данные.
У меня была эта проблема со странным поведением: очистка кеша браузера не устранила это, но очистка файлов cookie (то есть файла cookie идентификатора сеанса PHP) решила проблему.
В дополнение к другим предложениям вы можете получить ошибки токена CSRF, если ваше хранилище сеанса не работает.
В недавнем случае мой коллега изменил 'session_prefix' на значение, в котором был пробел.
Это нарушило хранилище сеанса, что, в свою очередь, означало, что моя форма не могла получить токен CSRF из сеанса.
У меня недавно была эта ошибка. Оказалось, что мои настройки cookie были неправильными в config.yml. Добавление настроек cookie_path и cookie_domain в framework.session исправило это.
Недавно у меня была такая же проблема, и мой случай еще не упоминался здесь:
Проблема заключалась в том, что я тестировал его в домене localhost . Я не уверен, почему именно это было проблемой, но она начала работать после того, как я добавил псевдоним имени хоста для localhost в /etc/hosts , например:
Возможно, что-то не так с сеансом при использовании Apache и localhost в качестве домена. Если кто-нибудь может уточнить в комментариях, я был бы счастлив отредактировать этот ответ, чтобы включить более подробную информацию.
Если вы не хотите использовать form_row или form_rest и просто хотите получить доступ к значению _token в вашем шаблоне веточки. Используйте следующее:
В моем случае у меня возникла проблема с аннотацией maxSize в сущности, поэтому я увеличил ее с 2048 до 20048.
Надеюсь, что этот ответ поможет!
Если вы преобразовали форму из простого HTML в twig, убедитесь, что вы не пропустили удаление закрывающего тега . Глупая ошибка, но, как я обнаружил, это возможная причина проблемы.
Когда я получил эту ошибку, я сначала не мог ее понять. Я использую form_start() и form_end() для создания формы, поэтому мне не нужно явно добавлять токен с form_row(form._token) или использовать form_rest() , чтобы получить это. Он уже должен был быть автоматически добавлен form_end() .
Проблема заключалась в том, что представление, с которым я работал, было тем, которое я преобразовал из простого HTML в twig, и я пропустил удаление закрывающего тега , поэтому вместо:
На самом деле это похоже на то, что может вызвать ошибку, но, очевидно, это не так, поэтому, когда form_end() выводит form_rest() , форма уже закрыта. Фактически сгенерированный источник страницы формы был таким:
Очевидно, решение состоит в том, чтобы удалить лишний закрывающий тег и, возможно, выпить еще кофе.
Исправление: очистите все файлы cookie для рассматриваемого домена, убедитесь, что вы не запускаете несколько приложений в одном домене с разными портами.
У меня была такая же ошибка, но в моем случае проблема заключалась в том, что мое приложение использовало несколько доменов первого уровня, в то время как файл cookie использовал один. Удаление cookie_domain: ".%domain%" из framework.session в config.yml привело к тому, что файлы cookie по умолчанию использовались в любом домене, в котором была форма, и это устранило проблему.
Вы должны помнить, что токен CSRF хранится в сеансе, поэтому эта проблема также может возникать из-за неправильной обработки сеанса. Если вы работаете на локальном хосте, проверьте, например, если домен cookie сеанса установлен правильно (в PHP он должен быть пустым на локальном хосте).
Похоже, это проблема при использовании начальной загрузки, если только вы не визуализируете форму с помощью >. Кроме того, проблемы возникают только при вводе type = "hidden". Если вы проверите страницу с формой, вы обнаружите, что скрытый ввод вообще не является частью разметки или отображается, но не отправляется по какой-либо причине. Как было предложено выше, добавление > или обертывание ввода, как показано ниже, должно помочь.
Символ CSRF недействителен. Повторите отправку формы
ОТВЕТЫ
Ответ 1
Вам нужно добавить _token в вашу форму i.e
На данный момент в вашей форме отсутствует поле токена CSRF. Если вы используете функции формы твига для рендеринга вашей формы, например form(form) , это автоматически отобразит поле маркера CSRF для вас, но ваш код показывает, что вы создаете форму с необработанным HTML, например , поэтому вам нужно вручную отобразить поле.
Или просто добавьте > перед закрывающим тегом формы.
Согласно документам
Это отображает все поля, которые еще не были отображены для данного форма. Это хорошая идея всегда иметь это где-то внутри вашей формы так как это сделает скрытые поля для вас и сделает все поля, которые вы забыли чтобы сделать более очевидным (поскольку он отобразит поле для вас).
Ответ 2
Эта опция в php.ini вызывает проблему
Проблема в том, что поле _token пропускает запрос PUT (GET), поэтому вам нужно увеличить значение.
Также это касается больших файлов. Увеличение
Ответ 3
Это происходит потому, что формы по умолчанию содержат защиту CSRF, которая в некоторых случаях не нужна.
Вы можете отключить эту защиту CSRF в своем классе формы в методе getDefaultOptions следующим образом:
Если вы не хотите отключать защиту CSRF, вам необходимо отобразить поле защиты CSRF в вашей форме. Это можно сделать, используя > в вашем файле вида, например:
> отображает все поля, которые вы не ввели вручную.
Ответ 4
Перед тегом поставьте:
Он автоматически вставляет другие важные (скрытые) входы.
Ответ 5
В дополнение к предложениям других вы можете получить ошибки токена CSRF, если ваша память сеанса не работает.
В недавнем случае мой коллега изменил "session_prefix" на значение, в котором было пробел.
Это сломало хранилище сеансов, что, в свою очередь, означало, что моя форма не могла получить токен CSRF из сеанса.
Ответ 6
У меня была эта проблема со странным поведением: очистка кеша браузера не исправила его, но очистка файлов cookie (то есть файлов cookie сеанса PHP) решила проблему.
Это нужно сделать после того, как вы проверили все другие ответы, включая проверку того, что у вас есть токен в поле ввода скрытой формы.
Ответ 7
У меня была эта ошибка в последнее время. Оказывается, мои настройки cookie были неправильными в config.yml. Добавление настроек cookie_path и cookie_domain в framework.session исправлено.
Ответ 8
Недавно я столкнулся с той же проблемой, и мой случай был чем-то, о чем здесь еще не говорилось:
Проблема была в том, что я тестировал его в домене localhost . Я не уверен, почему именно это было проблемой, но она начала работать после того, как я добавил псевдоним имени хоста для localhost в /etc/hosts следующим образом:
Возможно, что-то не так с сеансом при использовании Apache и localhost в качестве домена. Если кто-то может уточнить комментарии, я был бы рад отредактировать этот ответ, чтобы включить больше деталей.
Ответ 9
Если вы не хотите использовать form_row или form_rest и хотите получить доступ к значению _token в шаблоне ветки. Используйте следующее:
Ответ 10
В моем случае у меня возникла проблема с аннотацией maxSize в сущности, поэтому я увеличил ее с 2048 по 2004 год.
надеюсь, что этот ответ поможет!
Ответ 11
Если вы преобразовали форму из простого HTML в веточку, убедитесь, что вы не пропустили удаление закрывающего тега . Глупая ошибка, но поскольку я обнаружил это возможную причину этой проблемы.
Когда я получил эту ошибку, я не мог понять это сначала. Я использую form_start() и form_end() для создания формы, поэтому мне не нужно явно добавлять токен с помощью form_row(form._token) или использовать form_rest() для его получения. Он должен быть добавлен автоматически form_end() .
Проблема заключалась в том, что представление, с которым я работал, было тем, что я преобразовал из простого HTML в веточку, и я пропустил удаление закрывающего тега , поэтому вместо:
Это похоже на то, что может вызвать ошибку, но, по-видимому, это не так, поэтому, когда form_end() выводит form_rest() , форма уже закрыта. Фактически созданный источник страницы формы был таким:
Очевидно, что решение состоит в том, чтобы удалить дополнительный закрывающий тег и, возможно, выпить еще немного кофе.
Ответ 12
Исправление: очистите все куки для данного домена, убедитесь, что вы не запускаете несколько приложений в одном домене с разными портами.
Ответ 13
У меня была та же ошибка, но в моем случае проблема заключалась в том, что мое приложение использовало несколько доменов первого уровня, в то время как cookie использовал один. Удаление cookie_domain: ".%domain%" из framework.session в config.yml приводило к тому, что cookie по умолчанию использовался для любого домена, на котором была форма, и это config.yml проблему.
Ответ 14
Это кажется проблемой при использовании bootstrap, если вы не передаете форму >. Кроме того, проблемы возникают только при вводе типа = "скрытый". Если вы проверите страницу с помощью формы, вы обнаружите, что скрытый ввод не является частью разметки вообще или визуализируется, но не представляется по какой-либо причине. Как было предложено выше, добавление > или перенос ввода, как показано ниже, должен сделать трюк.
I usually have this problem when the form loads from cache. For example, logging out opens the login page again in my app and if the user just leaves that page open until they want to login the next time it will fail. Do you have any cache rules either in your response header or in your .htaccess?
Hi @fun2life thanks for your tip. I don't believe I have any cache rules in my response header, I haven't added any, but how would I check this? Regarding .htaccess files I found the following files: /home/lushawn/.cache/composer/.htaccess /home/lushawn/.config/composer/.htaccess /home/lushawn/.local/share/composer/.htaccess All of which have "Deny from all" written in them. Could this be an issue?
Could you try to change your register.html.twig form to only "<< form_start(registrationForm) >> << form_end(registrationForm) >>" and see if it works with the automatic rendering. Also try adding a SubmitType to the registration form instead of adding manually a submit button.<>
Not directly on topic but out of the box Symfony uses PHP's native session handler which on my linux system points to /var/lib/php/sessions. The docs show how to point it to var/cache if you want. Clearing it out might help though probably not. Looks like you used the make:auth and make:registration-form commands which seem to work for me. I assume you are using the Symfony development server?
Hello @alexcm thanks for your suggestion. I just tried this on the reg form and I get more strange behaviour. On initial registration attempt I get the following error: Key "errors" for array with keys "value, attr, form, id, name, full_name, disabled, label, label_format, label_html, multipart, block_prefixes, unique_block_prefix, row_attr, translation_domain, label_translation_parameters, attr_translation_parameters, priority, cache_key, clicked" does not exist. Then if I go back or navigate through links to the reg form and reattempt to register, it works. This is also repeatable
Ознакомиться с самой идеей атаки CSRF можно на классических ресурсах:
Выдержка из ответа на SO:
Как от нее защититься?
Эффективным и общепринятым на сегодня способом защиты от CSRF-Атаки является токен. Под токеном имеется в виду случайный набор байт, который сервер передает клиенту, а клиент возвращает серверу.
Защита сводится к проверке токена, который сгенерировал сервер, и токена, который прислал пользователь.
А что, собственно, защищать?
Если вы пишете свой Web-Сервис в соотвествии со стандартом RFC7231, то методы GET , HEAD , OPTIONS и TRACE являются безопасными: они предназначены только для получения информации и не должны изменять состояние сервера.
Таким образом, защищать необходимо небезопасные методы, к которым относятся: POST , PUT , DELETE , PATCH .
На Habrahabr опубликована статья от Yandex, в которой описано, почему писать свои сервисы нужно, руководствуясь стандартом.
Требования к токену:
- Уникальный токен для каждой операции
- Действует единожды
- Имеет размер, устойчивый к подбору
- Сгенерирован криптографически стойким генератором псевдослучайных чисел
- Имеет ограниченное время жизни
На первом MeetUp'е PDUG Тимур Юнусов (руководитель отдела безопасности банковских
систем Positive Technologies) рассказывал, почему именно такие требования предъявляются к CSRF-Токену и чем грозит пренебрежение ими.
Требования к Web-Сервису и окружению:
Отсутствие XSS уязвимостей
Внедренный злоумышленником скрипт имеет возможность отправлять запрос к серверу от имени пользователя и читать его без каких-либо препятствий.
Таким образом, XSS уязвимости могут быть использованы для получения текущего токена.
Отсутствие malware на машине клиента
Если злоумышленник имеет возможность запускать софт на машине клиента, то он может получить любые данные, имеющиеся в браузере.
Методы защиты
Существует 3 метода использования токенов для защиты web-сервисов от CSRF атак:
Synchronizer Tokens
Простой подход, использующийся повсеместно. Требует хранения токена на стороне сервера.
При старте сессии на стороне сервера генерируется токен.
Токен кладется в хранилище данных сессии (т.е. сохраняется на стороне сервера для последующей проверки)
В ответ на запрос (который стартовал сессию) клиенту возвращается токен.
Если рендеринг происходит на сервере, то токен может возвращаться внутри HTML, как, например, одно из полей формы, или внутри тега.
В случае, если ответ возвращается для JS приложения, токен можно передавать в header (часто для этого используют X-CSRF-Token )
При последующих запросах клиент обязан передать токен серверу для проверки.
При рендере контента сервером токен принято возвращать внутри POST данных формы.
JS приложения обычно присылают XHR запросы с header ( X-CSRF-Token ), содержащим токен.
При получения запроса небезопасным методом ( POST , PUT , DELETE , PATCH ) сервер обязан проверить на идентичность токен из данных сессии и токен, который прислал клиент.
Если оба токена совпадают, то запрос не подвергся CSRF-Атаке, в ином случае — логируем событие и отклоняем запрос.
На выходе имеем:
Защита от CSRF на хорошем уровне
Токен обновляется только при пересоздании сессии, а это происходит, когда сессия истекает
Во время жизни одной сессии все действия будут проверяться по одному токену.
Если произойдет утечка токена, то злоумышленник сможет выполнить CSRF-Атаку на любой запрос и в течение долгого срока. А это не есть хорошо.
Бесплатная поддержка multi-tab в браузере.
Токен не инвалидируется после выполнения запроса, что позволяет разработчику не заботиться о синхронизации токена в разных табах браузера, так как токен всегда один.
Double Submit Cookie
Этот подход не требует хранения данных на стороне сервера, а значит, является Stateless. Используется, если вы хотите уметь быстро и качественно масштабировать свой Web-сервис горизонтально.
Идея в том, чтобы отдать токен клиенту двумя методами: в куках и в одном из параметров ответа (header или внутри HTML).
При запросе от клиента на стороне сервера генерируется токен. В ответе токен возвращается в cookie (например, X-CSRF-Token ) и в одном из параметров ответа (в header или внутри HTML).
В последующих запросах клиент обязан предоставлять оба полученных ранее токена. Один как cookie, другой либо как header, либо внутри POST данных формы.
При получении запроса небезопасным методом ( POST , PUT , DELETE , PATCH ) сервер обязан проверить на идентичность токен из cookie и токен, который явно прислал клиент.
Если оба токена совпадают, то запрос не подвергся CSRF-Атаке, в ином случае — логируем событие и отклоняем запрос.
На выходе имеем:
Stateless CSRF защиту.
Таким образом, если ваш сервис доступен на домене 3-го уровня, а злоумышленник имеет возможность зарегистрировать свой ресурс на вашем домене 2-го уровня, то устанавливайте cookie на свой домен явно.
Encrypted Token
Так же как и Double Submit, является Stateless подходом. Основная — если вы зашифруете надежным алгоритмом какие-то данные и передадите их клиенту, то клиент не сможет их подделать, не зная ключа. Этот подход не требует использования cookie. Токен передаётся клиенту только в параметрах ответа.
В данном подходе токеном являются факты, зашифрованные ключом. Минимально необходимые факты — это идентификатор пользователя и timestamp времени генерации токена. Ключ не должен быть известен клиенту.
При запросе от клиента на стороне сервера генерируется токен.
Генерация токена состоит в зашифровке фактов, необходимых для валидации токена в дальнейшем.
Минимально необходимые факты — это идентификатор пользователя и timestamp. В ответе токен возвращается в одном из параметров ответа (В header или внутри HTML).
В последующих запросах клиент обязан предоставлять полученный ранее токен.
При получения запроса небезопасным методом ( POST , PUT , DELETE , PATCH ) сервер обязан валидировать токен, полученный от клиента.
Валидация токена заключается в его расшифровке и сравнения фактов, полученных после расшифровки, с реальными. (Проверка timestamp необходима для ограничения времени жизни токена)
Если расшифровать не удалось либо факты не совпадают, считается, что запрос подвергся CSRF-Атаке.
На выходе имеем:
Stateless CSRF защиту
Нет необходимости хранить данные в cookie
О реализации
Таким образом мы получаем токен, который меняется постоянно.
Конечно, возникает вопрос организации multi-tab работы.
Синхронизация токенов между табами может быть реализована с использованием localStorage и его StorageEvent
Ограничиваем время жизни cookie, которое содержит токен, разумным значением. Например 30 минут.
Используем TLS для предотвращения MITM
Размер токена не менее 32 байт.
Генерируем токен криптографически стойким генератором псевдослучайных чисел.
Для этого можно использовать системные функции:
Что еще нужно знать?
Токены — обязательная защита от CSRF.
Проверяйте, но не полагайтесь только на заголовки: Host , Origin , Referer
Не передавайте токены в URL
Same Site
Такой атрибут даст возможность разработчикам явно указывать, что cookie не нужно передавать, если запрос идет с сайта, отличного от того, на котором cookie была установлена. А, значит, у нас появится возможность защищать ресурсы от CSRF без использования дополнительных инструментов.
В настоящее время в сфере обеспечения безопасности веб-сайтов и приложений возникла очень интересная ситуация: с одной стороны, некоторые разработчики уделяют особое внимание безопасности, с другой, они напрочь забывают о некоторых видах атак и не считают ошибки, позволяющие выполнить данные атаки, уязвимостями. Например, к такой категории можно отнести CSRF (Сross Site Request Forgery). Эта атака позволяет производить различные действия на уязвимом сайте от имени авторизованного пользователя. Если вы не слышали о таком, то я рекомендую прочитать соответствующую статью в Википедии, чтобы иметь общее представление об этом виде атак. Основная часть статьи предназначена тем, кто обеспокоен правильной защитой своих сайтов от CSRF.
Замечание 1: если подходить формально, то CSRF является атакой, а не уязвимостью, как и XSS. Уязвимостью является неправильная обработка входных данных, а CSRF это использует.
Замечание 2: если какие-то ошибки показались вам очевидными и не заслуживающими упоминания, то я рад за вас. Однако данный материал основан на реальных уязвимостях крупных сайтов, а каждый пункт показывает ошибку какой-либо команды разработчиков, обернувшуюся дырой в безопасности.
Список ошибок:
1) Полностью отсутствует защита от CSRF.
По своему опыту могу сказать, что в настоящее время это — самая распространенная ошибка. Ее можно встретить как на малопосещаемых блогах, так и на крупных проектах. Единственная уважительная причина не использовать защиту от данного вида атак — сайт не хранит никакие пользовательские данные, а вы не используете панель администратора для редактирования материалов.
2) Защищены не все запросы.
3) Использование для защиты от CSRF чего-либо, кроме токенов.
Как насчет использования капчи? Я слышал достаточно большое количество вопросов от разработчиков о возможности их использования для защиты от атаки. Мой однозначный ответ — нет. Во-первых, вы явно не будете заставлять пользователя вводить капчу на каждый чих: это приведет к ошибке № 2. Во-вторых, далеко не все способы реализации капч обеспечат вас должной защитой, которую злоумышленник не сможет обойти. Поскольку эта тема является весьма спорной и актуальной, в дальнейшем я посвящу ей отдельную статью.
Для защиты от CSRF вы должны использовать анти-CSRF токены и только их. Лишь они обеспечивают должную защиту ваших сайтов. В общих чертах о механизме токенов рассказано в Википедии:
Другим распространённым способом защиты является механизм, при котором с каждой сессией пользователя ассоциируется дополнительный секретный ключ, предназначенный для выполнения запросов. Пользователь посылает этот ключ среди параметров каждого запроса, и перед выполнением каких-либо действий сервер проверяет этот ключ. Преимуществом данного механизма, по сравнению с проверкой Referer, является гарантированная защита от атак данного типа. Недостатками же являются: требования возможности организации пользовательских сессий и динамической генерации HTML-кода активных страниц сайта.
4) Отсутствие проверки анти-CSRF токена при обработке запроса.
5) Частичная проверка анти-CSRF токена.
Данную ошибку я встретил сразу на нескольких крупных сайтах рунета в разных вариациях. Например, один из сайтов использовал токены вида «Имя_пользователя.Текущее_время.Длинное_случайное_число». При этом проверялось только соответствие имени пользователя в токене и логина того, от чьего имени был отправлен запрос. Это немного усложняет атаку, но не делает ее невозможной.
6) Возможность использовать один токен для разных пользователей.
Данную ошибку я встретил один раз, но на достаточно крупном сайте, так что считаю необходимым упомянуть ее. Злоумышленник мог зарегистрировать новый аккаунт на сайте, скопировать токен из исходного кода страницы и использовать его для CSRF. Не допускайте такой ошибки, так как она полностью уничтожает все плюсы токенов на вашем сайте.
7) Недостаточная длина токена.
Ваш токен должен быть настолько длинным, чтобы злоумышленник потратил на его подбор как минимум столько же времени, сколько и на подбор пароля пользователя. Я встречал токены из 2 символов, они не сильно помогут, если кто-то очень сильно захочет осуществить CSRF-атаку.
8) Предсказумые токены.
При разработке алгоритма генерации токена обязательно используйте случайные данные в токене (совет актуален, если вы разрабатываете всю систему с нуля. В случае использования фреймворка или CMS вы должны полагаться на их разработчиков). Поверьте, токен вида «md5(user_id)» — очень плохая идея.
9) Отсутствие токенов в админ-панели или системе для сотрудников техподдержки.
Даже если весь доступный вашим пользователям сайт защищен от CSRF, то не стоит забывать про панель администратора. В одной известной в узких кругах биллинг-системе было много CSRF именно в панели администратора (хотя они были и в публичной части системы, но это не так важно). И любой, кто знал структуру запросов, мог использовать CSRF-атаку на сотрудника техподдержки и получить доступ к данным всех клиентов компании, использующей данную биллинг-систему. Единственная проблема — необходимо узнать структуру запросов: для этого можно использовать социальную инженерию, скачать копию в открытых источниках или просто взломать менее защищенный сайт, использующий такую же систему.
10) Передача токенов в открытом виде, особенно в GET-запросах.
Наличие этих ошибок даже на крупных и серьезных сайтах показывает, что проблема защиты от CSRF-атак стоит достаточно остро. Безусловно, этот список не является исчерпывающим. Я уверен, что можно найти еще несколько ошибок и способов их эксплуатации. Однако если вы проверите свои сайты на наличие проблем, описанных в этой статье, и исправите их, то значительно повысите защищенность проекта.
Читайте также: