Как защитить Formit от Curl
Всем доброго времени суток.
На новый год начали атаковать сайт спамом, опытным путем выяснили, что атака идет примерно таким скриптом:
curl -X POST -F 'name=linuxize22' -F 'phone=%2B7+(111)+111-1111' -F 'af_action=b410d612437cea16aebde937ffa79a3b' -F 'pageId=1' \
-H «X-Requested-With: XMLHttpRequest» \
--cookie «PHPSESSID=e12556e3b7093e9f82411af39f471e9f» \
адрес.сайта/assets/components/ajaxform/action.php
Капча не спасает от такой атаки (или может я коряво ее настроил?), но в личном кабинете капчи никаких плохих сессий она на замечает. А я вот спокойно таким скриптом шлю письма, когда она работает, таким же образом (как мне кажется) шлет письма и недоброжелатель.
Есть ли возможность защититься от такой атаки и интегрировать капчу на уровне самого formit, а не на уровне отдельной формы? Или может .htaccess спасет? Спам прекращается только когда ломаю formit добавляя в начале скрипта return;
На новый год начали атаковать сайт спамом, опытным путем выяснили, что атака идет примерно таким скриптом:
curl -X POST -F 'name=linuxize22' -F 'phone=%2B7+(111)+111-1111' -F 'af_action=b410d612437cea16aebde937ffa79a3b' -F 'pageId=1' \
-H «X-Requested-With: XMLHttpRequest» \
--cookie «PHPSESSID=e12556e3b7093e9f82411af39f471e9f» \
адрес.сайта/assets/components/ajaxform/action.php
Капча не спасает от такой атаки (или может я коряво ее настроил?), но в личном кабинете капчи никаких плохих сессий она на замечает. А я вот спокойно таким скриптом шлю письма, когда она работает, таким же образом (как мне кажется) шлет письма и недоброжелатель.
Есть ли возможность защититься от такой атаки и интегрировать капчу на уровне самого formit, а не на уровне отдельной формы? Или может .htaccess спасет? Спам прекращается только когда ломаю formit добавляя в начале скрипта return;
Комментарии: 17
Покажите вызовы сниппета AjaxForm на вашем сайте. Отправить форму с сайта без заполнения капчи точно невозможно?
[[!AjaxForm?
&snippet=`FormIt`
&form=`tplCallbackForm`
&emailTpl=`tplCallbackMessage`
&hooks=`spam,email,recaptchav3`
&emailSubject=`Заказ обратного звонка с сайта [[++site_url]]`
&emailTo=`[[++ms2_email_manager]]`
&validate=`name:required,phone:required,email:blank`
&validationErrorMessage=`В форме содержатся ошибки!`
&successMessage=`Сообщение успешно отправлено!`
]]
&snippet=`FormIt`
&form=`tplCallbackForm`
&emailTpl=`tplCallbackMessage`
&hooks=`spam,email,recaptchav3`
&emailSubject=`Заказ обратного звонка с сайта [[++site_url]]`
&emailTo=`[[++ms2_email_manager]]`
&validate=`name:required,phone:required,email:blank`
&validationErrorMessage=`В форме содержатся ошибки!`
&successMessage=`Сообщение успешно отправлено!`
]]
хуки вызываются в порядке их указания:
&hooks=`spam,email,recaptchav3`
у вас значит проверка spam (не знаю, что там), далее отправляется письмо, далее проверка рекапчи… только смысл то её проверять, письмо уже отправлено.
&hooks=`spam,email,recaptchav3`
у вас значит проверка spam (не знаю, что там), далее отправляется письмо, далее проверка рекапчи… только смысл то её проверять, письмо уже отправлено.
Поменял местами, поставил хук капчи первым. С сайта форма отправляется (пишет все ок), на почту не приходят, в логах ошибка — httpdocs/core/cache/includes/elements/modsnippet/94.include.cache.php: 84) Failed to load Recaptcha class. Но скриптом через курл письма отлично приходят))) Капча не помогает защищаться от курла(
ну смотри…
AjaxForm лишь прокидывает данные на FormIt.
Для того, чтобы это все работало — при рендере формы в сессию записываются $scriptPtoperties с которыми вызывался AjaxForm, эти данные записаны в сессии с ключем, который передается в af_action.
Получается, что в сессии эти данные есть по крайней мере она не пуста)
Потом FormIt вызывает хуки по очереди:
— spam он там как-то email проверяет, у тебя в форме я каких-либо email не вижу, думаю что в итоге этот хук вообще ничего не делает у тебя;
— далее правильно вызывать recaptchav3, судя по логам он с ошибкой работает. Если посмотрим в код, то сообщение в логе «Failed to load Recaptcha class» означает и то, что хук вернет false. Все, FormIt должен прекратить обработку, до хука email, который отправит письмо, дело не дойдет.
AjaxForm лишь прокидывает данные на FormIt.
Для того, чтобы это все работало — при рендере формы в сессию записываются $scriptPtoperties с которыми вызывался AjaxForm, эти данные записаны в сессии с ключем, который передается в af_action.
Получается, что в сессии эти данные есть по крайней мере она не пуста)
Потом FormIt вызывает хуки по очереди:
— spam он там как-то email проверяет, у тебя в форме я каких-либо email не вижу, думаю что в итоге этот хук вообще ничего не делает у тебя;
— далее правильно вызывать recaptchav3, судя по логам он с ошибкой работает. Если посмотрим в код, то сообщение в логе «Failed to load Recaptcha class» означает и то, что хук вернет false. Все, FormIt должен прекратить обработку, до хука email, который отправит письмо, дело не дойдет.
Это все понятно, но поломанный ajaxform не мешает отправлять злоумышленнику отправлять курлом письма. Тут вопрос не в том, как пресекать действия с помощью рекапчи, а как запретить курлом отправлять письма напрямую через formit?
Капчу поставил другую, на морде все отрабатывает отлично, без прохождения капчи форма не уходит, а через курл как шли письма — так и идут. Куда еще можно копать? Почему капча не работает на системном уровне? Где то может я какую то настройку упускаю?
Капча не появляется, так как скрипт не определяет, что визит подозрительный. Я если не вызываю сниппет на страницы, отправить курлом письмо все равно получается. Получается даже в том случае, когда на сайте не остается ни одной формы.
Поменяй AjaxForm на SendIt
А без смены нет решений? Это сам по себе AjaxForm дырявый?
Можно попробовать эту строку заменить на такую
$hash = $_SESSION['afhash'] = md5(http_build_query($scriptProperties));
А на этой строке добавить проверкуif(!$_SESSION['afhash'] || !$_REQUEST['af_action'] || $_REQUEST['af_action'] !== $_SESSION['afhash']){
echo $AjaxForm->error('af_err_action_ns');
}
И не забудь рассказать помогло или нет, интересно же)))
Не помогло)
Это потому что сниппет вызывается. А вообще идея в том, чтобы генерировать токен, записывать его в сессию и передавать на фронт. А при отправке формы передавать обратно на сервер и а файле action.php проверять равен ли переданный токен записанному в сессию и вообще есть ли этот токен. Генерировать можно в плагине на событие OnHandleRequest. Передавать на фронт через $_COOKIE. Вставлять форму JS.
Я пока победил атаки только сменой AjaxForm на другую обертку Formit. Курл работать перестал, жду пока новых атак)
Тоже столкнулся с такой проблемой, не понимал откуда спам. Стоял AjaxForm, поменял на FetchIt один фиг через день началось.
Как вариант конечно создать дубликат action.php, назвать аля fsdfjsfjsoidfjsofsdofsd.php, заменить везде обращения action.php на новый файл. в оригинальном action.php return можно какую то ошибку все время возвращать для правдоподобности.
Но если прям всерьез взялись за атаку, то и этот файл быстро найдут, посмотрят куда отправляются запросы.
Как вариант конечно создать дубликат action.php, назвать аля fsdfjsfjsoidfjsofsdofsd.php, заменить везде обращения action.php на новый файл. в оригинальном action.php return можно какую то ошибку все время возвращать для правдоподобности.
Но если прям всерьез взялись за атаку, то и этот файл быстро найдут, посмотрят куда отправляются запросы.
AjaxForm перестали поддерживать уже, переходи на другую обертку Formit, там более защищено все
SendIt с версии 1.1.2 защищён от подобных атак.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.