Антиспам для FormIt с генерацией случайной строки
Всем привет! Задался вопросом антиспама для форм сайта. Спам сыпался каждый день и надо было это исправлять…
Как будем защищать сайт: Генерируем случайную строку, вставляем в валидацию вызова формы и в саму форму.
Итак, погнали:
Данная статья написана больше для новичков, способ защиты ещё на стадии тестирования и доработки.
И всё) Главное, сниппет [[randString]] вызывать кешируемым!
P.S. Выражаю благодарность @Алексей Смирнов за данный метод защиты, а так же можно просто поставить AjaxFormItLogin где @Артур Шевченко такой метод внедрил.
Поблагодарить автора, а также немного порадовать других активных участников сообщества можно,
отправив донат одним из следующих способов:
Как будем защищать сайт: Генерируем случайную строку, вставляем в валидацию вызова формы и в саму форму.
Итак, погнали:
- Создаём сниппет randString
<?php $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $output = 'antispam-'.substr(str_shuffle($permitted_chars), 0, 16); return $output;
- Добавляем в вызов формы, в параметр &validate
nobot:contains=^[[randString]]^
- Добавляем класс ajax_form форме.
- Добавляем скрипт внизу сайта (обычно у меня это чанк [[$scripts]])
<script> $(function(){ $('.ajax_form').append('<input hidden name="nobot" value="[[randString]]">') }); </script>
Данная статья написана больше для новичков, способ защиты ещё на стадии тестирования и доработки.
И всё) Главное, сниппет [[randString]] вызывать кешируемым!
P.S. Выражаю благодарность @Алексей Смирнов за данный метод защиты, а так же можно просто поставить AjaxFormItLogin где @Артур Шевченко такой метод внедрил.
Поблагодарить автора, а также немного порадовать других активных участников сообщества можно,
отправив донат одним из следующих способов:
- На карту Тинькофф https://tinkoff.ru/sl/2V9U9RrcJZP
- На YooMoney https://yoomoney.ru/fundraise/RPkkYwNcL7A.230131
- На Qiwi кошелек https://qiwi.com/p/77012827737
- Казахстан Каспи по номеру +7(701)282-77-37
Комментарии: 23
Спасибо за очередной способ борьбы со спамом, но честно говоря, я не понял как он работает и почему именно должен защитить от спама.
Вы генерируете случайную строку, вставляете ее в форму через jquery, а затем в валидаторе проверяете ее наличие.
А почему собственно она должна отсутствовать? Спам боты точно так же выполняют весь javascript на странице, как и обычный пользователь и этот инпут будет добавлен в форму и в случае спамбота.
Но если вы говорите что вам помогло, то вам везет и видимо пока что вас атакуют самые примитивные боты)
Я пробовал подобный подход, но не просто append при загрузки странице, а например добавление скрытого поля в форму только после того как кто то кликнул по кнопке, открывающей конкретную форму, пробовал добавлять поле при события наведения мыши на открытой модальное окно и так далее. И в любом случаем через день два спам снова возобновлялся в том же объеме.
Признаюсь, что ни один из способов «автоматического» определения — спам, не спам не дал для меня результата. Лучшего способа с пока что 100 процентным результатом удалось добиться только при таком антиспаме, где пользователю предлагается ответить на вопросы. Как в каптче от гугла — типа выберите все мосты на 8 фотографиях.
Вы генерируете случайную строку, вставляете ее в форму через jquery, а затем в валидаторе проверяете ее наличие.
А почему собственно она должна отсутствовать? Спам боты точно так же выполняют весь javascript на странице, как и обычный пользователь и этот инпут будет добавлен в форму и в случае спамбота.
Но если вы говорите что вам помогло, то вам везет и видимо пока что вас атакуют самые примитивные боты)
Я пробовал подобный подход, но не просто append при загрузки странице, а например добавление скрытого поля в форму только после того как кто то кликнул по кнопке, открывающей конкретную форму, пробовал добавлять поле при события наведения мыши на открытой модальное окно и так далее. И в любом случаем через день два спам снова возобновлялся в том же объеме.
Признаюсь, что ни один из способов «автоматического» определения — спам, не спам не дал для меня результата. Лучшего способа с пока что 100 процентным результатом удалось добиться только при таком антиспаме, где пользователю предлагается ответить на вопросы. Как в каптче от гугла — типа выберите все мосты на 8 фотографиях.
Я согласен с сомнительностью защиты, но как меня уверили, он работает. Я тоже, считаю, что генерация случайной строки на фронте не защитить от серьёзных спам-ботов.
Надеюсь в ближайшее время, улучшить способ защиты перенеся проверку случайной строки полностью на сторону сервера, пока думаю как это сделать…
Надеюсь в ближайшее время, улучшить способ защиты перенеся проверку случайной строки полностью на сторону сервера, пока думаю как это сделать…
И не совсем мне ясно, в чем ообще смысл сниппета и генерирования каждый раз случайной строки. Ведь валидатор проверяет только факт наличия заполненности такого поля. На мой взгляд, если руками один раз вписать value для этого инпута ничего не измениться. Или я не прав?
Смысл генерации только в попытке защититься от не очень продвинутых ботов, для которых такой способ защиты непреодолим…
но согласитесть, нет разницы, будет в каждой форме в этом инпуте написано одна и таже строка (value='hello world') или генерируемая каждый раз разная строка — на антиспам это не должно влиять. Ведь валидатор проверяет только факт заполненности этого поля.
Согласен, случайная строка по сути тут как заготовка для более правильного решения… На днях буду прорабатывать этот момент.
Знаете, я разуверился в возможности написания «атоматического» спамбота, когда не так давно произошло следующее.
Возникла на работе задача сделать быстрое решени по переносу сайтов с одного места в другое.
Как ее решал я — писал bash скрипты, которые по ssh выполнли создание архивов, дампы баз, потом подключались на другой сервер, туда все копировали, проводили постобработку типа сброса кеша, замены путей в файлах конфигураций и так далее.
Как ее решил мой коллега. Написал на jave программу которая тупо запускает браузер и в нем полностью имитирует все действия человека. Тоесть его программа сначала вошла на хостинг откуда нужно перенести, сама там авторизовалась, сама преешла на нужные страницу в панели хостинга, создала архивы, как это делал бы человек, скачала их. ПОтом авторизовалась на другом хостинге и там создала новый сайт, залила туда архив и так далее. Все это визуально у тебя перед глазами, ты только сидишь и смотришь.
И тут я понял, что при таких возможностях, нет никаких разумных способов отличить бота от человека. Только задавать вопросы боту, на которые ему будет сложно ответить.
Возникла на работе задача сделать быстрое решени по переносу сайтов с одного места в другое.
Как ее решал я — писал bash скрипты, которые по ssh выполнли создание архивов, дампы баз, потом подключались на другой сервер, туда все копировали, проводили постобработку типа сброса кеша, замены путей в файлах конфигураций и так далее.
Как ее решил мой коллега. Написал на jave программу которая тупо запускает браузер и в нем полностью имитирует все действия человека. Тоесть его программа сначала вошла на хостинг откуда нужно перенести, сама там авторизовалась, сама преешла на нужные страницу в панели хостинга, создала архивы, как это делал бы человек, скачала их. ПОтом авторизовалась на другом хостинге и там создала новый сайт, залила туда архив и так далее. Все это визуально у тебя перед глазами, ты только сидишь и смотришь.
И тут я понял, что при таких возможностях, нет никаких разумных способов отличить бота от человека. Только задавать вопросы боту, на которые ему будет сложно ответить.
В целом, данный способ ещё на стадии проверки и доработки. Использую его в связке с Google reCaptchaV3.
Если вкратце у меня работает так (Подсмотрено у Артур Шевченко, спасибо ему)
1. тоже генерируется рандомная строка
2. тоже проверяется через contains
3. и полю nobot эта рандомная строка присвоится только(!) при наведении на форму, а у вас как я понял сразу.
У меня полет нормальный
1. тоже генерируется рандомная строка
2. тоже проверяется через contains
3. и полю nobot эта рандомная строка присвоится только(!) при наведении на форму, а у вас как я понял сразу.
У меня полет нормальный
{set $secret = md5(rand(0,999999999))}
{'!AjaxForm' | snippet :[
....
'secret' => $secret ,
'validate' => 'vscval:contains=^'~$secret~'^'
....
]}
//В форме
<input type="hidden" name="vscval" style="display:none" data-vscval="{$_pls['secret']}">
//Js
function watchForms(){
if(document.querySelector('form')){
document.querySelectorAll('form').forEach((ff) => {
ff.addEventListener('mousemove', (e) => {
if(ff.querySelector('input[name="vscval"]')){
let inpSecret = ff.querySelector('input[name="vscval"]'),
inpSecretData = inpSecret.getAttribute('data-vscval');
if(inpSecret.value == ''){
inpSecret.value = inpSecretData;
}
}
});
});
}
}
watchForms()
Тоже хотел сделать именно при наведении, но решил, напишу сначала простенькую статью. А там глядишь люди дадут хорошие советы, и я перепишу статью… Благодарю! За это утро, мне уже несколько человек дали хорошие решения, которые я обязательно тут покажу!
Добрый день. Как себя ведёт событие mousemove на мобильных устройствах?
На телефоне все норм, сейчас проверил на одном из сайтов форма отправляется. Ну если что можно на событие touchmove повесить
На многих сайтах я делал простой append (точнее prepend) в форму с фиксированной строкой, не заморачивался с генерацией случайно строки.
Спама было мало, но тоже подтверждаю на некоторых сайтах спам-боты пробивали и сыпался спам, тут как повезет. Так как способ простой, то ставил в формы по умолчанию на все сайты. Защищает от ботов, которые не умеют в JavaScript (интересно много таких сейчас?)
Спама было мало, но тоже подтверждаю на некоторых сайтах спам-боты пробивали и сыпался спам, тут как повезет. Так как способ простой, то ставил в формы по умолчанию на все сайты. Защищает от ботов, которые не умеют в JavaScript (интересно много таких сейчас?)
В FormIt есть встроенная защита от спама, в виде математического уравнения, см. docs.modx.com/current/ru/extras/formit/formit.hooks/math Но мало видел, что ее используют, хотя, думаю, что нормально работает.
Неужели способ «создать поле email и требовать, чтобы оно всегда было пустым» уже не работает?)
Даже не знаю) Не пробовал так делать.
На данный момент скажу вот что, данный метод, что я описал в статье, действительно работает. На сайте где я его внедрил, спам как отрезало. Но я понимаю, что метод хоть и работает, но он ещё не доработан. Мне мой хороший товарищ Дмитрий Волинский дал способ защиты с записью случайной строки в сессию и отлавливанием её прехуком… Буду проверять такой метод на другом проекте, и как будут «плоды», опишу способ реализации в этой статье.
На данный момент скажу вот что, данный метод, что я описал в статье, действительно работает. На сайте где я его внедрил, спам как отрезало. Но я понимаю, что метод хоть и работает, но он ещё не доработан. Мне мой хороший товарищ Дмитрий Волинский дал способ защиты с записью случайной строки в сессию и отлавливанием её прехуком… Буду проверять такой метод на другом проекте, и как будут «плоды», опишу способ реализации в этой статье.
Второй месяц уже пошёл, вроде полёт нормальный, у тебя как проходит?
Всё тихо, спамеров не видно ?
А продолжение будет? интересная затейка
У меня работает уже второй месяц, с тех пор как узнал про него. До этого был просто ужас!))
Изобрел CSRF токен и радуется
:P
Можно немного усложнить задачу для спамеров на стандартном синтаксисе. Т.к. случайная строка генерируется и не меняется при обновлении страницы. Решить этот вопрос можно через плейсхолдер. Я делал форму на FetchIt, поэтому приведу код на нём:
В чанке popup.form.tpl необходимо добавить в форму скрытое поле:
ну и также прикрутил js отсюда modx.pro/howto/23926#comment-139070
[[!randString:toPlaceholder=`randString`]]
[[!FetchIt?
&snippet=`FormIt`
&submitVar=`popup`
&form=`popup.form.tpl`
&emailTpl=`emailForm.tpl`
&hooks=`FormItSaveForm,email,sendTelegram`
&emailSubject=`Заявка на обратный звонок`
&emailTo=`[[++email_to]]`
&emailFrom=`test@test.ru`
&randString=`[[!+randString]]`
&validate=`antispam:contains=^[[!+randString]]^,name:required,phone:required,popup_request_conditions:required`
&validationErrorMessage=`Необходимо заполнить все поля формы!`
&successMessage=`Спасибо! Ваша заявка отправлена!`
&errTpl=`Необходимо согласиться с обработкой персональных данных`
]]
В чанке popup.form.tpl необходимо добавить в форму скрытое поле:
<input type="hidden" name="antispam" style="display:none" data-antispam="[[!+randString]]">
ну и также прикрутил js отсюда modx.pro/howto/23926#comment-139070
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.