Спам в формах AjaxForm/FetchIt? Защищаем ЛЮБЫЕ точки входа в MODX с помощью IskWaf



Всем привет!

В Telegram-чате регулярно поднимается один и тот же вопрос: «Как защититься от спама в форме? У меня стоит FetchIt или AjaxForm, капчу на странице вывел, а спам всё равно летит тоннами!»

Я решил эту проблему в своем компоненте IskWaf (MODX3 / MODX2), и в этой заметке хочу рассказать, как теперь можно обеспечить тотальную защиту вашего сайта.


Проблема в том, что боты часто игнорируют саму страницу и шлют запросы напрямую на PHP-обработчик (коннектор) формы. И в этот момент большинство стандартных средств защиты, работающих на уровне плагинов MODX, просто не срабатывают.

Почему стандартные плагины бессильны?

Давайте разберемся, почему так происходит. Когда пользователь открывает страницу сайта, запрос проходит через главный файл index.php, MODX инициализирует все свои системы и вызывает событие OnHandleRequest. Ваш плагин (или мой IskWaf в режиме по умолчанию) ловит это событие и выполняет проверку.

Но когда спам-бот отправляет POST-запрос напрямую на assets/components/fetchit/action.php, происходит следующее:

Веб-сервер видит запрос к существующему PHP-файлу.

Он напрямую исполняет action.php, минуя index.php и весь основной жизненный цикл MODX.

Событие OnHandleRequest никогда не вызывается.

Плагин-защитник просто спит.

Результат —форма беззащитна перед прямыми атаками.

IskWaf: От плагина к полноценному щиту безопасности

Осознав эту проблему, я полностью переработал архитектуру компонента IskWaf. В последней версии появилась возможность защищать любые PHP-файлы на вашем сайте.

Вся логика блокировок (по IP-адресу, User-Agent, Referrer, стоп-словам в URI) была вынесена в единый сервисный класс. Теперь мы можем подключить защитника там, где он нужнее всего — прямо в уязвимых коннекторах.

Инструкция: Защищаем коннектор FetchIt за 2 минуты

Давайте на реальном примере посмотрим, как добавить защиту IskWaf на популярный обработчик форм FetchIt.

Предполагается, что компонент IskWaf у вас уже установлен из репозитория.

Шаг 1: Находим файл-обработчик
Чаще всего коннектор, который обрабатывает AJAX-запросы FetchIt, лежит здесь:
assets/components/fetchit/action.php

Шаг 2: Подключаем «Стража» IskWaf

Откройте этот файл и в самое его начало, добавьте всего одну строку кода:

Для MODX3
require_once dirname(__FILE__, 4) . '/core/components/iskwaf/iskwaf-guard.php';
Для MODX 2

require_once dirname(__FILE__, 4) . '/core/components/iskwaf2x/iskwaf2x.guard.php';

IskWaf — это инструмент, правила создаете вы

Важно понимать: IskWaf — это не волшебная коробка с одной кнопкой «включить защиту», а мощный конструктор правил. Он дает вам возможность анализировать каждый запрос по множеству параметров, но эффективность защиты напрямую зависит от правил, которые вы создадите. Он дает вам молоток и гвозди, а вы решаете, куда их забивать.

Данный функционал доступен по для компонента для MODX3 IskWaf 3.0.9-pl
https://modstore.pro/packages/utilities/iskwaf

Для MODX2 iskwaf2x 1.0.4-pl
https://modstore.pro/packages/utilities/iskwaf2x
Ivan K.
08 июля 2025, 20:44
modx.pro
1
868
+14
Поблагодарить автора Отправить деньги

Комментарии: 9

Aleksandr Huz
09 июля 2025, 10:58
0
Все супер, но не нравится только правка исходников.

Он напрямую исполняет action.php, минуя index.php и весь основной жизненный цикл MODX.
Событие OnHandleRequest никогда не вызывается.
Все-таки не минуя index.php, но из-за того, что включен режим API (MODX_API_MODE), плагины действительно не сработают.

То есть, разработчикам нужно просто отключать режим API, чтобы плагины заработали, и тогда не придется лезть в исходники.

Но если компонент не обновлять, то и так сойдет))
    Ivan K.
    09 июля 2025, 11:33
    0
    У компонентов FetchIt AjaxForm нет обновлений уже очень давно.

    У меня есть идея использовать настройку auto_prepend_file в php.ini. Тогда не нужно будет править исходники. Не знаю стоит ли реализовывать и как это скажется на производительности.
      Ivan K.
      09 июля 2025, 12:01
      0
      Все-таки не минуя index.php, но из-за того, что включен режим API (MODX_API_MODE), плагины действительно не сработают.
      Вы знаете вы ввергли меня в сомнения)
      Попробовал, и выяснил, включен или нет API — не имеет значения плагин не срабатывает, если напрямую обращаться, например, к assets/components/fetchit/action.php
        Aleksandr Huz
        09 июля 2025, 12:36
        0
        Пришлось проверить)))

        POST-запрос на assets/components/fetchit/action.php с выключенным MODX_API_MODE вызывает как минимум событие OnHandleRequest.
          Ivan K.
          09 июля 2025, 13:43
          +1
          Точно плагин срабатывает (нормально проверил) с выключенным MODX_API_MODE.

          Но чтобы выключить MODX_API_MODE тоже нужно править исходник, того же Fetchit, например.
            Ivan K.
            09 июля 2025, 14:04
            0
            Значит я не зря все-таки вынес логику в сервисный класс))
      Руслан
      10 июля 2025, 11:30
      0
      А разве csrf не решит проблему?
        Ivan K.
        10 июля 2025, 12:17
        0
        Нет
        Max
        Max
        20 июля 2025, 11:48
        0
        Для защиты от прямого обращения можно немного допилить файл action.
        1. Создать сниппет который создает куку, который ставим в прехуки формы обратной связи, код примерно такой:
        <?php
        $_SESSION['trueuser'] = 1;
        return true;
        Затем уже в скрипте action.php любого плагина который занимается отправкой, проверяем эту куку:
        //проверяем на бота
        if($_SESSION['trueuser'] != 1){ //не прошел проверку
            echo  $AjaxForm->success('Сообщение успешно отправлено.'); //скажем что все ок =)))
        Все гуглится в яндексе по запросу «MODX прямое обращение к action.php» =)))
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          9