MODX CSRFHelper — защита форм FormIt и AjaxForm от CSRF атак

MODX CSRFHelper - защита форм FormIt и AjaxForm от CSRF атак MODX Revo
В данном уроке научимся защищать контактные формы на FormIt и AjaxForm от CSRF атак при помощи бесплатного MODX дополнения CSRFHelper.

Что такое CSRF атака

CSRF (Cross-Site Request Forgery, также XSRF) – опаснейшая атака, которая приводит к тому, что хакер может выполнить на неподготовленном сайте массу различных действий от имени других, зарегистрированных посетителей.

Какие это действия – отправка ли сообщений, перевод денег со счёта на счёт или смена паролей – зависят от сайта, но в любом случае эта атака входит в образовательный минимум веб-разработчика.

Что такое CSRFHelper и как его установить

CSRFHelper — бесплатное MODX, которое поможет защитить ваши формы FormIt и AjaxForm от атак CSRF.

Установка CSRFHelper стандартная из основного репозитория.

Защита MODX форм от CSRF атак по шагам

1. Добавление токена в форму

В форме добавьте следующее скрытое поле:

 <input type="hidden" name="csrf_token" value="[[!csrfhelper? &key=`simple-form`]]">

Примечание: у каждой формы должно быть уникальное значение &key .

Для конфиденциальных форм вы также можете добавить свойство &singleUse со значением 1, которое гарантирует, что каждый запрос получит уникальный токен CSRF. Если вы не укажете этот параметр, токен для формы останется неизменным в течение 24 часов.

Чтобы показать ошибку, когда токен CSRF не совпадает, или если он не может быть безопасно сгенерирован на вашем сервере, добавьте следующее в подходящее место в вашей форме:

 [[!+fi.error.csrf_token:notempty=`<div class="error">[[!+fi.error.csrf_token]]</div>`]]

2. Проверка токена с помощью хука

Теперь, когда мы отправляем токен, мы также должны его проверить. Делаем это хук csrfhelper_formit.

В вызове FormIt или AjaxForm добавьте csrfhelper_formitк своему &hooks.

Также добавьте свойство &csrfKeyс хуком для токена CSRF; это должно быть уникальным для каждой уникальной формы и соответствовать &keyв csrfhelperвызове сниппета. В приведенном выше примере это было установлено на simple-form.

Примеры форм с защитой от CSRF атак

Вот пример из официальной документации по плагину:

[[!FormIt?
   &hooks=`spam,csrfhelper_formit,email,redirect`
   &redirectTo=`71`
   &validate=`nospam:blank,
      name:required,
      email:email:required,
      subject:required,
      text:required:stripTags`
   &csrfKey=`simple-form`
]]

<h2>Contact Form</h2>
 
[[!+fi.validation_error_message:notempty=`<p>[[!+fi.validation_error_message]]</p>`]]
 
<form action="[[~[[*id]]]]" method="post" class="form">
     [[!+fi.error.csrf_token:notempty=`<div class="error">[[!+fi.error.csrf_token]]</div>`]]
     <input type="hidden" name="csrf_token" value="[[!csrfhelper? &key=`simple-form`]]">
    <input type="hidden" name="nospam" value="" />

    <label for="name">
        Name:
        <span class="error">[[!+fi.error.name]]</span>
    </label>
    <input type="text" name="name" id="name" value="[[!+fi.name]]" />

    <label for="email">
        Email:
        <span class="error">[[!+fi.error.email]]</span>
    </label>
    <input type="text" name="email" id="email" value="[[!+fi.email]]" />
 
    <label for="subject">
        Subject:
        <span class="error">[[!+fi.error.subject]]</span>
    </label>
    <input type="text" name="subject" id="subject" value="[[!+fi.subject]]" />
 
    <label for="text">
        Message:
        <span class="error">[[!+fi.error.text]]</span>
    </label>
    <textarea name="text" id="text" cols="55" rows="7" value="[[!+fi.text]]">[[!+fi.text]]</textarea>
  
    <div class="form-buttons">
        <input type="submit" value="Send Contact Inquiry" />
    </div>
</form>

И дополнительно, в качестве примера возьму форму на AjaxForm и fenom со страницы контактов, которую делали в этом уроке. Сразу модифицирую ее вывод и чанк.

Вывод станет таким:

{'!AjaxForm' | snippet : [
    'snippet' => 'FormIt',
    'hooks' => 'csrfhelper_formit,email',
    'validate' => 'name:required:maxLength=^21^,email:email:required,message:required:minLength=^30^',
    'form' => 'contact_form',
    'emailTpl' => 'tplForm',
    'emailTo' => $_modx->config.emailsender,
    'emailFrom' => 'noretly@modx-revolution.ru',
    'emailSubject' => 'Сообщение со страницы контакты на сайте ' ~ $_modx->config.site_name,
    'successMessage' => '<div class="contact-form-success alert alert-success mt-4"><strong>Успешно!</strong> Ваше сообщение отправлено нам.</div>',
    'validationErrorMessage' => '<div class="contact-form-success alert alert-danger mt-4"><strong>Ошибка!</strong> Произошла ошибка при отправке вашего сообщения.</div>',
    'csrfKey' => 'contact_form'
]}

А чанк, таким:

<form class="ajax_form af_example contact-form custom-form-style-1" action="{$_modx->makeUrl($_modx->resource.id, '', '', 'full')}" method="post">
    {$fi.successMessage}
    {$fi.validation_error_message}
    {$fi.error.csrf_token}
    <input type="hidden" name="csrf_token" value="{'!csrfhelper' | snippet : [ 'key' => 'contact_form' ]}">
    <div class="row row-gutter-sm">
        <div class="form-group col mb-3">
            <input type="text" value="" class="form-control" name="name" placeholder="Ваше имя">
            <span class="error_name">{$fi.error.name}</span>
        </div>
    </div>
    <div class="row row-gutter-sm">
        <div class="form-group col mb-3">
            <input type="email" value="" class="form-control" name="email" placeholder="Ваш E-mail">
            <span class="error_email">{$fi.error.email}</span>
        </div>
    </div>
    <div class="row">
        <div class="form-group col mb-3">
            <textarea rows="4" class="form-control" name="message" placeholder="Сообщение"></textarea>
            <span class="error_message">{$fi.error.message}</span>
        </div>
    </div>
    <div class="row appear-animation" data-appear-animation="fadeInUpShorterPlus" data-appear-animation-delay="1500">
        <div class="form-group col mb-0">
            <button type="submit" class="btn btn-primary btn-modern font-weight-bold custom-btn-border-radius custom-btn-arrow-effect-1 text-3 px-5 py-3">
            	ОТПРАВИТЬ
            	<svg class="ms-2" version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
					<polygon stroke="#FFF" stroke-width="0.1" fill="#FFF" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>
				</svg>
            </button>
        </div>
    </div>
</form>

Рекомендую во все формы на сайте внедрить защиту от CSRF атак + внедрить пару способов борьбы со спамом без капч, так вы отсекете огромный поток спама (защита будет не хуже чем гугл капча и не будет напрягать пользователей).

Ниже приведен полный пример, основанный на примере простой контактной формы для FormIt. В следующем уроке сделаем хлебные крошки.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 1 оценка, среднее 5 из 5 )
Web-Revenue.ru
Добавить комментарий