Комментарии ()

  1. Andres 01 августа 2022, 15:16 # 0
    Сайт бомбический, Ман!
    +
    T
    >

    Система антиспама для форм обратной связи без капчи

    /* Превью

    Рабочий на 100% варик, ни разу не был преодолён ботами, прикручиваем к сайту на MODX для примера

    */

    0. Такс такс… Спам на сайте? давайте-ка его убирать.

    Данный метод прокатит практически в любом случае, логика проста, спам-боты заполняют все поля форм, и за частую отключат js, по этому добавляем с помощью js в форму поле, если это поле будет отсутствовать или будет заполнено, форма не отправиться

    1. Добавляем JavaScript (с jQuery) 

    Он будет добавлять скрытые поля к формам

    $(function(){
     // Антиспам
     if($('.ajax_form').length)
      $.each('.ajax_form', function(){
       $(this).append('<input type="text" name="org" value="" class="_org" style="visability: hidden; height: 0; width: 0; padding: 0; border: none;" />')
      })
     // Антиспам х  
    })

    * где '.ajax_form' класс формы

    2. Обработчик перед отправкой сообщения

    Далее пишем php код который будет проверять присутствует ли поле org и пустое ли оно, если всё ок, отправляем письмо на почту

    <?php
    if(isset($_POST['org'])){
     if($_POST['org']!=''){
      // Поле org какогото *** заполненно
      die();
     }else{
      // Далее код для отправки сообщения
     }
    }else{
     // Поле org отсутствует
     die();
    }

    Готово, СПАМ не пройдёт! (:

    Далее код для CMS MODX


    Для версии Revo с приложениями FromIt и AjaxForm

    2.1. Добавляем снипет, именуем например validate

    <?php
    function text_error(){
     return false;
     die();
    }
    if(isset($_POST['org'])){
     if($hook->getValue('org')!=''){
       $modx->log(xPDO::LOG_LEVEL_ERROR, 'Ошибка заполнения формы: не пустое поле антиспама');
       $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
       text_error();
     }else{
      $modx->log(xPDO::LOG_LEVEL_ERROR, 'Форма успешно отправлена');
      $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
      return true;
     }
    }else{
     $modx->log(xPDO::LOG_LEVEL_ERROR, 'Ошибка заполнения формы: нет поля антиспама');
     $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
     text_error();
    }

    Этот код будет сохранять весь спам в лог MODX и можно будет убедится что он действительно действует, кроме того даже успешные отправки будет сохранять, если вдруг с формами где то накосячили, и не пришли данные с формы, то в логе можно будет посмореть все отправленные данные

    2.2. При вызове формы в чанке добавляем хук с названием этого снипета (validate)

    &hooks=`validate, email, FormItSaveForm`

    Для версии EVO с приложениями eForm и FormLister

    2.2. Добавляем снипет «validate»

    <?php
    function validate(){
     if(isset($_POST['org'])){
      if($_POST['org']!=''){
       die();
      }else{
       
      }
     }else{
      die();
     }
    }

    Перед выводом формы выводим снипет

    [!validate!]

    Если используете FormLister
    В выводе FormLister добавляем

    [!FormLister?
     &prepareProcess=`validate`

    Для чистого eForm

    [!eForm?
     &eFormOnValidate=`validate`

    АПД:

    25.06.2020 03:15:00

    Таки это произошло, 6 лет без спама используя этот способ, и вот, нашёлся бот который его прошёл, он использует JS, и повторяет поведенческие файторы, наводит мышкой на поле, и якобы печатает. Из особых примет, заходит на сайт на прямую, работает на линуксе, яндекс его определяет как россиянина, хотя его IP это никак не выдаёт, постоянно разные и из разных стран, может хуяндекс знает чего то чего не знают сервисы определения IP? ..

    В общем пораскинув мозгами я дополнил этот способ обхода спама одной хитрожопой штукой.

    Надо поменять местами названия полей, например поле phone, назвать как email, а email как phone, через атрибут name, чтобы не запутать человека-пользователя, и при проверке искать в поле собаку. Бот заполняет поля по их name, и пишет в email почту, но мы то знаем что человек не видящий кода будет писать в поле email номер телефона, а там никакой собаки быть не может, пока что..

    Дополнение в коде хука выглядит следующим образом В месте где предыдущие проверки успешно проходят, заменяем успешную отправку на этот код.

    $sEmail = $hook->getValue('PHONE');
    $sPhone = $hook->getValue('EMAIL');
    if ( strripos($sPhone, '@') === false) {
      $modx->log(xPDO::LOG_LEVEL_ERROR, 'Успешное заполнение формы');
      $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
      return true;
    } else {
      $modx->log(xPDO::LOG_LEVEL_ERROR, 'Умный бот, форма не отправленна');
      $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
      text_error();
    }

    Чтобы убрать автозаполнение и не запутать пользователя нужно добовить полям атрибут autocomplete="off"

    Ну и опять небольшой прорыв) во все поля вставляется минуя все проверки, ссылки и спам текст, для фикса прикручиваем проверку на www и на http например в поле телефона

    
            if ( 
              strripos($sPhone, 'www') === false
              && strripos($sPhone, 'http') === false
             ) {
               $modx->log(xPDO::LOG_LEVEL_ERROR, 'Успешное заполнение формы');
               $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
               $modx->setPlaceholder('fi.successMessage','<p>Ваша заявка отправлена. <br>С Вами обязательно свяжутся</p>');
               return true;
            }
            else {
              $modx->log(xPDO::LOG_LEVEL_ERROR, 'Ошибка заполнения формы: Умный бот, проверку на http или www не прошёл, форма не отправленна');
              $modx->log(xPDO::LOG_LEVEL_ERROR, print_r($_POST, 1));
              $modx->setPlaceholder('fi.successMessage','spam');
              text_error();  
            }