Веб-разработчик
0,0
рейтинг
28 февраля 2012 в 20:14

Разработка → Защищаем веб-формы от спама без CAPTCHA — 2: Ботобор

Три года назад на Хабре была опубликована статья «Form Spam Bot Blocker: Защищаем Web-формы без CAPTCHA!», рассказывающая о принципиально отличном от CAPTCHA решении для PHP по защите форм от спам-ботов. Это решение основано на идеях, изложенных в своих статьях Филом Хааком (Phil Haack) — Honeypot Captcha и Недом Батчелдером (Ned Batchelder) — Stopping spambots with hashes and honeypots. К сожалению, предложенный в статье класс, написан для PHP4 и не развивается с 2007-го года. Хочу предложить вашему вниманию его аналог на PHP5.

Ботобор



Ботобор — библиотека, написанная на PHP 5.0, предназначенная для защиты от заполнения веб-форм роботами. Используемые ей методы, незаметны для посетителей-людей.

Для выявления роботов Ботобор использует следующие проверки:

  • несовпадение значения REFERER с URL, на котором расположена форма;
  • слишком маленький промежуток между показом формы и её отправкой (настраивается);
  • слишком большой промежуток между показом формы и её отправкой (настраивается);
  • заполнение поля-приманки.


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

Примеры


Простой пример

Фрагмент кода, создающего форму:
require 'botobor.php';

// Получите разметку формы тем способом, который предусмотрен у вас в проекте, например:
$html = $form->getHTML();
// Создайте объект-обёртку:
$bform = new Botobor_Form($html);
// Получите новую разметку формы
$html = $bform->getCode();


Фрагмент кода, обрабатывающего данные формы:
require 'botobor.php';

if (Botobor_Keeper::isHuman())
{
  // Форма отправлена человеком, можно обрабатывать её.
}


Пример настройки формы

Фрагмент кода, создающего форму:
// пусть $html содержит код формы
$bform = new Botobor_Form($html);
// отключаем поля-приманки
$bform->setCheck('honeypots', false);
// устанавливаем нижний предел заполнения формы в 2 секунды
$bform->setDelay(2); 
// устанавливаем верхний предел заполнения формы в 60 минут
$bform->setLifetime(60);
$html = $bform->getCode();

В остальном всё также как и в первом примере.

Что у ней внутре?



Что делает Ботбор с кодом формы

В конструкторе Botobor_Form принимает HTML-код формы. В этот код, после открывающего тега <form>, добавляется скрытый (display: none) <div>, содержащий input[type=hidden] с мета-данными формы. Эти мета-данные хранят подписанную информацию о времени создания формы, установленных опциях и т. д. В этот же скрытый блок Ботобор может вставлять поля-приманки.

Поля-приманки

Поля-приманки предназначены для отлова роботов-пауков, которые находят формы самостоятельно. Такие роботы, как правило, ищут в форме знакомые поля (например, name) и заполняют их. Ботобор может добавить в форму скрытые от человека (при помощи CSS) поля с такими именами. Человек оставит эти поля пустыми (т. к. просто не увидит), а робот заполнит и тем самым выдаст себя.

По умолчанию в коде формы ищутся поля с любым из следующих имён: «name», «mail», «email» (список настраивается). У каждого найденного поля имя меняется на сгенерированную случайным образом комбинацию символов и создаётся скрытое средствами CSS поле с оригинальным именем.

Обратное преобразование имён будет сделано во время вызова метода Botobor_Keeper::handleRequest() или Botobor_Keeper::isHuman().

Буду рад, если кому-то пригодится.
Михаил Красильников @Mekras
карма
18,9
рейтинг 0,0
Веб-разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • +9
    Некоторые люди отключают передачу referer. И если люди, отключающие cookies, сами виноваты, что у них не работает большинство сайтов (без cookies принципиально невозможно сделать некоторые вещи), то без referer всё должно работать, никакой критичной функциональности он не обеспечивает.

    Слишком большой промежуток — странное ограничение. Человек, например, мог просто отойти от компьютера на час, а затем вернуться и дописать комментарий.
    • +1
      Как я и написал, разработчик может сам выбрать какие проверки уместны, в зависимости от условий стоящей пред ним задачи. Конкретно проверка на большой промежуток предназначена для того, чтобы нельзя было сохранить форму с её мета-данными и использовать её в будущем (через день, два, десять…).
    • +1
      Проверка-то правильная, но по-хорошему, если превышен некий интервал времени, нужно показывать пользователю форму с уже заполненными полями и просьбой «отправьте, пожалуйста, ещё раз». Пользователь переживёт, нажмёт кнопку лишний раз (случается это достаточно редко, чтобы доставлять неудобство), а для робота — будет сюрприз.
      • 0
        > Проверка-то правильная

        Чем проверка правильная? Пользователю нужно производить лишние действия, только потому, что программист не смог придумать ничего лучшего?

        Хорошо хоть в автомобилях на тормоз не нужно жать во второй раз, ради доказательства, что ты человек и хочешь затормозить.
        • 0
          По-моему, вы сильно преувеличиваете страдания пользователя. Простую форму больше часа будет заполнять один пользователь из тысячи, а на повторное нажатие «отправить» он потратит секунд эдак десять. С другой стороны, эта проверка отсечёт десяток спам-ботов, которые будут мешать и хозяевам сайта (нужно больше времени на модерацию), и посетителям (сложнее найти информацию), причём всем, а не единицам.

          Взвешивая плюсы и минусы, приходим к выводу…
          • +1
            Приходим к выводу о целесообразности ограничения на время заполнения формы :-)

            И всё таки — зачем ограничивать?

            Если этого требует проект — то целесообразнее делать узкоспециализированную проверку, которая будет специфична для проекта. В каком-то специфичном для проекта слое, а не в «универсальной» библиотеке.
    • +2
      а как отключить передачу реферер? Честно говоря, я даже не знаю.
      А вот боту послать любой реферер труда вообще не состовляет.

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

      Написать бота проблем нету. Я писал бота для онлайн-игры на юзер-скриптах. И не вижу как обойти такого бота. Только если контролировать движение мышки (все равно можно обмануть) или добавить какое-то всплывающее окошко (алерт, или confirm), которое должно заблокировать поведение скриптов.
      • +2
        Если форма заполняется долго, то это плохая форма.
        • +2
          Форма может заполняться быстро, а страница с ней быть открыта долго.

          Открыли статью хабра, пока прочитали статью, пока прочитали комменты…
          • 0
            К тому же если эта форма содержит комментарий (как например та форма в которой я пишу эти строки) то нужно время ещё чтоб упорядочить мысли (что с похмелья не всегда происходит быстро) =)
          • 0
            Разные проекты, разные задачи — разный набор проверок и параметров этих проверок.
            Если это форма комментария — можно установить большой lifetime, или вообще отключить проверку.
            Если это форма запроса звонка, расположенная на отдельной странице — можно установить lifetime поменьше.
            Никто разработчика не заставляет использовать все проверки со значениями по умолчанию.
            • 0
              > можно установить lifetime поменьше.

              Если защита работает и с отключенным пресловутым лайфтаймом — то зачем он вообще нужен?

              Минимальный лайфтайм не защищает потому, что можно попросить бота слать через паузу. Максимальный не защищает потому, что бот всё равно будет слать через минимальный интервал.

              Это я говорю о ботах, специально заточенных под проект. А незаточенные на примитивном csrf-поле споткнутся (которое так и так должно быть в форме).
              • +2
                Любая защита всегда многослойна и неабсолютна. Неверно говорить, что защита работает или не работает, всегда надо уточнять о каких случаях идёт речь. Каждый слой защиты — дополнительная страховка от определённого набора случаев. Ограничение lifetime защищает от программ вроде Хрумера, но оно не спасёт от примитивных пауков, работающих по принципу «нашёл форму — засабмитил». Зато от них спасёт ограничение Delay, которое, в свою очередь, не спасает от для Хрумера. И т. д.

                Защита от CSRF — ещё один слой, который может быть, а может и не быть. Например, зачем защита от CSRF на сайте, где нет регистрации пользователей?
                • 0
                  Никакой разницы нет, есть регистрация пользователей или нет — csrf нужен всегда.

                  По остальным пунктам согласен (потому и поставил +) :-)
                  • 0
                    > Никакой разницы нет, есть регистрация пользователей или нет — csrf нужен всегда.
                    Не поясните зачем?
                    • 0
                      Чтобы ваши формы были отправлены исключительно с вашего сайта, по определению.
                      • 0
                        Я тут подумал, по сути, мета-данные, добавляемые Ботобором в форму, это и есть маркер против CSRF. Потому что они содержат время создания страницы (т. е. уникальное значение), подписанное при помощи неизвестного посетителю ключа.
                        • 0
                          Тогда да, пардон.

                          ps: а какой смысл завязываться на шифрование вместо рандома? Если алгоритм и подпись утекут — то в них смысла никакого не будет. А рандом он и в африке рандом
                          • 0
                            Смысл в том, что требуется передача определённых данных, таких как время создания страницы и параметров проверок.

                            Если утечёт подпись и пойдёт спам, её легко сменить.
                            • 0
                              Генерить рандомный CSRF-токен, хранить его в сессии.
                              В форму время создания страницы и прочие вещи класть в открытом виде, засолить CSRF-токеном и положить рядом хэш от этого всего.
                              • 0
                                Изначально всё хранилось в сессии, потом почему-то было переделано без сессий. Надо вспомнить, почему. Но вообще, как вариант, такую возможность надо добавить (https://github.com/mekras/botobor/issues/7)
      • +2
        В последнее время стали попадаться такие капчи, что на разбор того, что там написано уходит времени больше, чем на заполнение формы.
    • –4
      > люди, отключающие cookies, сами виноваты, что у них не работает большинство сайтов

      Где оно, большинство неработающих сайтов? Редко-редко такой попадается, и даже в таком случае почти всегда его можно заменить нормальным. Со скриптами похуже, но тоже примерно такая же ситуация.

      Люди, вывешивающие истеричные баннеры «сайт свёрстан под разрешение такое-то», «сайт лучше всего работает в %browsername%» или «включите куки, а то..», кроме кривой улыбки ничего не вызывают.
      • –1
        Я конечно могу ошибаться, мой багаж знаний в области веб-программирования всё ещё растет, но как сделать нормальную авторизацию без cookie?
        • +1
          Полагаю, ?session=21EC20203AEA1069A2DD08002B30309D в каждой ссылке на сайте. Никогда такого не делал, но всякие phpBB вечно загаживают ссылки идентификаторами сессий даже при включенном печенье.
        • 0
          Например, передавать токен в строке запроса. Так сделано в ASP.NET в том случае, если куки отключены.
          • 0
            Не очень хорошее решение: токен потом палится во всех мыслимых местах, от логов прокси и веб-сервера до результатов поиска яндекса.
            • 0
              Скажем приемлимое решение в отсутствие куков.

              >>токен потом палится во всех мыслимых местах, от логов прокси и веб-сервера
              У токена есть время жизни.

              >>до результатов поиска яндекса
              Откуда? Яндекс бот сможет залогиниться?
              • 0
                Вы, видимо, пропустили весь скандал с смс-ками мегафона, товарами сексшопов и хранилищем документов на госсайте. Все эти эпизоды уходили корнями в то, что разработчики сайтов считали URL ужасно секретной штукой, а яндекс с его яндексбаром — нет.
                • 0
                  Допустим яндекс бар собирает URL аутентифицированного пользователя. С окончанием сессии от этих адрессов с токеном внутри не будет никакого прока — вы будете перенаправлены на страницу логина, так как время жизни токена истекло.
                  • 0
                    Возьмём, к примеру, Хабр. Я логинился на него в прошлом году. Если бы Хабр авторизовал пользователей по ключу в GET-строке, а я имел яндексбар, за это время можно было бы много раз зайти на хабр под моим логином и устроить мне кармасуицид.
                    • 0
                      Вы невнимательно читаете. Я уже 2 раза повторил, что у токена есть время жизни (серверная проверка). Ну не зайдете вы через, скажем 20 мин, под свой аккаунт с тем линком.
                      • 0
                        Я всё внимательно читаю. Не могу понять, как тогда честному пользователю избежать ежедвадцатиминутных выкидываний в форму входа?
                        • 0
                          >>избежать ежедвадцатиминутных выкидываний в форму входа

                          Обычно используют «sliding expiration» для сессий. Пользователь будет автоматически разлогинен через заданный промежуток времени в случае неактивности. Быть постоянно залогиненным, как это сделано на хабре, я считая небезопасным, но это имхо.
                          • 0
                            Ну это зависит от критичности системы, в которую логинишься. Я, например, не считаю опасным быть долго залогиненным на хабре, но считаю критичными те 20 минут, за которые токен в урле может уйти к посторонним лицам.
        • +1
          А зачем?
        • 0
          Basic Auth + HTTPS
        • 0
          Вопрос не так ставите. Да, без кук авторизовываться нельзя, но зачем мне авторизовываться на всех не входящих в белый список встречных-поперечных сайтах?
    • +2
      Реферер — стандартный функционал обеспечиваемый браузером. Без реферера запросто могут не работать критичные к безопасности вещи.
      Собственно реферер наравне с секретным токеном это один из пунктов проверки для многих защит от CSRF.
      • +1
        Реферер не отсылается при работе через HTTPS, с которого безопасность и начинается. Что такое «критичное к безопасности» не может работать без реферера?
        • 0
          Я не говорю об HTTPS. Обычный функционал веб сервиса нормально защищенный от XSS/CSRF может с большой долей вероятности проверять реферер в качестве дополнительной проверки на равне с секретным токеном.
          • +2
            Проверять-то может, но если перестаёт работать без реферера — у меня для этого «защищенного функционала» плохие новости.
            • 0
              Особенно меня смешат сайты, на которых каптча или скрипт принимающий формы выдает мне «hack attempt» если у меня отключен реферер. Впрочем, тот же хабр не работает с выключенным реферером.
              • +1
                зачем? вот приведите мне хоть один разумный аргумент, зачем его отключать?
                • 0
                  Его может резать различное ПО, как на компьютере пользователя, так и на узлах между. Зачем — авторов этого ПО стоит спросить (в своё время agnitum firewall резал), клиенты об этом могут даже и не знать
                • 0
                  Как зачем. Я не хочу что бы меня трекали по поисковым фразам, не хочу что бы знали откуда я пришел на сайт. Это мое лично дело. Приватность и все такое.

                  И зачем вы уводите разговор куда-то в сторону. Почему отключенный реф считается «hack attempt» или нелогичным/неправильным поведением? Почему тот же хабр не работает, если он отключен, хотя все понимают что при желании его можно подменить и все такое. Давно уже пора разработать стандарт позволяющий не парсить урл, содержащийся в каком-то там заголовке, а работающий с историей посетителя. Что за каменный век?
                  • 0
                    а) вы вряд ли отключаете куки. их достаточно, чтобы оттрекать вас по google analytics.
                    б) тему паранойи в интернете оставьте белкам истеричкам. пока вы не ищете рецепт бомбы и детское порно, какая вам разница, кто вас трекает?
                    в) _нельзя_ подменить referer. НЕЛЬЗЯ. все браузеры на попытку его подмены выдают эксепшн нарушения политики безопасности.
                    г) работать с историей посетителя нельзя по понятным причинам. вам весело будет, если зайдя на страничку с милым котёнком, сайт сольёт всю вашу историю за месяц? это куда серьёзнее analytics.
                    • 0
                      Я еще раз спрашиваю где тут hack attempt? Или отвечайте, или не буду с вами тут переписываться. Вы, я гляжу, читаете только то, с чем можно поспорить.

                      а) Что касается трекинга — у меня просто на outpost (старенький, в новом такое низя) заблокированы все подобные хосты, то есть браузер туда физически не попадает.
                      б) Не хочу и все. Имею полное право управлять софтом, которым я пользуюсь. И от этого не должен сходить с ума другой софт.
                      в) Под «подменой» я имел в виду ручную установку нужного мне заголовка в запросе.
                      г) Дак я и не говорил про «слить всю историю». Я всего лишь сказал, что нынешний способ неадекватен. На дворе 21 век, XML, API и куча других полезных аббревиатур.
                      • 0
                        _нормальный_пользователь_ не станет отключать Referer. вы отключили — значит 99% вероятности, что вы бот. написали hack attempt вместо 99% hack attempt.

                        и это, вы своими ответами никому одолжения не делаете. не нравится — не отвечайте.

                        а) вам тяжело, наверное. столько полезных сайтов в интернете из-за своей паранойи не видите.
                        б) засунуть кошку в микроволновку, а потом жаловаться на производителя микроволновок.
                        в) вы можете делать что угодно, см. б). без вашего ведома никто не может подменить referer.
                        г) и при чём здесь эти аббревиатуры? нынешний способ адекватен. вы его только почему-то не приемлете. сделают вам новый — вы и на него жаловаться будете. олсо, XML — это наследие прошлого века.
        • 0
          вы не правы. он отсылается. всегда. пойдите и проверьте фаербагом.
          • 0
            А, ну да, реферер режется только при переходе HTTPS > HTTP.
        • 0
          Athari> Реферер не отсылается при работе через HTTPS

          Что имеется в виду? Заглянул в HTTPS-лог своего сервера, реферер на месте.
  • 0
    ИМХО ваш проект имеет потенциал, но требует серьезной доработки. На данный момент сервис будет полезен только для защиты от типовых решений.
    Мне кажется, что следует добавить проверку через js, которая защищает от php ботов. (недавно была статья)
    Второй вариант потребует авторизации через OAuth, которая открывает возможность анализировать социальную активность пользователя и его друзей. Недавно были предложены идеи относительно «теории 6 рукопожатий», которая плохо работает с ботами, на этом можно и построить защиту.

    Какие у вас предложения?
    • 0
      По большому счёту библиотека и рассчитана на типовые решения, она позволяет быстро и просто защитить формы от роботов. Если у вас крупный проект, к тому же лакомый для спамеров, конечно, стоит подумать об индивидуальной и более сложной защите. А вот для сайтов, где пяток форм, вроде «обратной связи», Ботобора вполне хватит.
      • 0
        Для своих форумов на PhpBB делал такую защиту от роботов: дописал в страничку js-скрипт, который перед отправкой формы добавляет в неё еще одно поле, а на сервере соответственно проверку его наличия, т.е. по паре строк кода в двух файлах. И всё, боты отвалились. За пару лет ни одного (что странно — я ожидал, что хотя бы часть ботов умеет выполнять скрипты каким-нибудь встроенным IE). Позже перевел форум на другой движок, поэтому не могу сказать, насколько действенен этот метод сейчас; на новом сайте тоже без капчи, формы отправляются ajax'ом, и тоже ни одного бота по сей день — почти три года прошло с перехода. А до добавления этих js-штук спамеры просто замучили модераторов PhpBB-форумов.
  • 0
    Как раз недавно защищал один сайт от спама. Использовал:
    * стоп-слова на основе истории спама (англоязычная фарма);
    * ограничение по минимальному времени заполнения, которое рассчитывалось исходя из настраиваемой скорости 10 символов в секунду:
    * ограничение по максимальному времени набора (более 30 минут).

    Если это срабатывало, то форма возвращалась со всеми введёнными данными и каптчей и предложением подождать (если слишком быстро набрали) или отправить ещё раз, если слишком долго набирали. Причём временные ограничения начинались сначала. Для быстрого набора писалось сколько надо подождать.

    Ограничение сверху было использовано для того, если спамят через большой список полуавтоматом (например хрумером), то на него могут попасть. Либо если сохранили изначально форму с набором предустановленных полей. Метка времени начала подписывалась хэшем.

    Спам исчез совсем, т.е. моё предположение об автоматическом режиме подтвердилось.
  • +9
    Как-то нелогично использовать для setDelay($iSeconds) секунды, а для setLifetime($iMinutes) минуты.

    Дисклеймер — в код не заглядывал. Вывод сделан на основе комментариев в коде.
    // устанавливаем нижний предел заполнения формы в 2 секунды
    $bform->setDelay(2); 
    // устанавливаем верхний предел заполнения формы в 60 минут
    $bform->setLifetime(60);
    
    • –6
      Логично. Потому что Delay никогда не бывает больше минуты, а Lifetime, наоборот — не бывает меньше. Ну и задавать его в минутах просто удобнее для конечного разработчика.
      • +1
        чем удобнее-то? Вы задаете час как 60 минут. Может тогда в часах все делать? По моему это неверный подход и удобнее как раз в секундах (что-то типа час = 1*3600).

        А еще в php есть DateInterval

        $bform->setLifetime(new DateInterval(«PT1H»));
        • –1
          Удобнее тем, что задавать в секундах никогда надобности не возникает, а вот в минутах были случаи. Собственно, по умолчанию, там как раз (если не ошибаюсь) 30 минут стоит. По опыту, подходит для большинства случаев. Пока менять в большую сторону приходилось только на паре проектов.

          DateInterval появился только в PHP 5.3, а нам надо было обеспечить работу библиотеки и под более ранними версиями 5-й ветки.
  • 0
    До полей ловушек в свое время и сам допер, а вот проверка на реферера — зачет!

    Правда у меня там еще JS заполняет некоторые поля строго определенными значениями.

    А что, без JS сейчас не обходится ни один приличный сервис будь то гугло/яндекс карты, вконтактик и много чего еще массового.
  • НЛО прилетело и опубликовало эту надпись здесь
  • +2
    А кто-то сейчас сидит и увлеченно дописывает алгоритмы своих спамботов.
  • 0
    Вариант 1. делаем скрытое поле-приманку с названием email — сразу же отваливается 95% ботов. Вариант 2. Отправляем форму не через submit формы, а аяксом, заодно заменяем submit button на div с onclick="..." (а в action у формы указываем адрес ловушки). Сразу же отваливается оставшаяся часть ботов (ну и юзеры без яваскрипта, вроде меня, но я все равно не заполняю веб-формы).

    А проверять реферер/куки — не работающая хрень.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Чем плоха настройка через массив параметров?
      new MyClass(array(
        'foo' => 123,
        'bar' => 234
      ));
      
  • 0
    > Идея: REFERER может быть, может не быть. Основывать на этом защиту — создавать проблемы пользователю.

    Защита на этом не основывается. Это лишь одна из возможных проверок.

    > Поля приманки могут создать проблемы с автозаполнением — абсолютно легальные пользователи отсеются.

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

    > несколько классов в одном файле
    Обычно мы так не делаем, но здесь это вполне сознательное решение. Причина — компактность и простота подключения к сайту.

    > статические методы
    Что не так со статическими методами? В данном случае они выполняют функцию эмуляции пространства имён.

    > обращение к глобальным переменным внутри класса
    Если речь идёт про обращение к $_SERVER в Botobor_Keeper::handleRequest, то это на усмотрение разработчика. Методу можно передать аргумент $req, и тогда он $_SERVER трогать не будет. Если у Вас есть идеи, как сделать лучше — буду рад услышать.

    > парсинг html регуляркой
    Ваши предложения?

    > настройки через массивы параметров.
    Где?
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        > Я не против процедурного программирования, но если уж выбирать его, то зачем создавать объекты?
        А тут объекты и не нужны. Просто не хочется создавать глобальные переменные вместо статических свойств как сейчас.

        >В РHP есть пространства имён, не нужно ничего «эмулировать».
        В PHP > 5.0, < 5.3 их нет. А нам приходится использовать библиотеку на хостингах где нет 5.3.

        > здесь невозможно использовать autoload, нужен require.
        Это почему же нельзя? Мы используем, там, где это надо. Все имена классов начинаются с «Botobor_». Сделать функцию автозагрузки элементарно.

        > запрашивать необходимые параметры в конструкторе
        Да пожалуйста! Если в конкретном проекте это имеет смысл — напишите обёртку, которая будет передавать в метод аргумент $req, и тогда метод не будет трогать $_SERVER. Но нам, бывает, приходится иметь дело с проектами, которые написаны не нами и по которым нет документации, а защитить форму надо «вот уже прям щас». Бывают проекты, где и фреймвока-то нет, просто набор скриптов. Разные, в общем, проекты бывают. И часто обработка $_SERVER — вполне допустимый компромисс между красотой решения и затратами на реализацию.

        > html нужно разбирать с помощью XML-парсера
        Кому нужно? :-) Нет, как расширение функциональности, в виде отдельного модуля, это конечно можно сделать. Я даже обязательно тикет такой открою. Но, как я уже писал выше, мы сталкиваемся с самыми разными проектами. И на многих из них, использование парсера будет напоминать забивание гвоздя под крючок для картины при помощи промышленного пневмомолота. Это конечно круто, высокотехнологично… но смысл?

        Знаете, я некоторое время назад, тоже был пуристом, как и Вы. Но в последнее время стал всё чаще задумываться и об экономической целесообразности.
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            В мире, кроме крайностей, ещё существует многое между ними.
            • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                Я с этим полностью согласен. Именно поэтому используются статические члены, а не функции с глобальными переменными. Именно поэтому предусмотрена альтернатива прямой работе с $_SERVER.

                Ещё хотелось бы вспомнить одну из притч Пути Тестивуса:

                Ученик спросил двух мастеров программистов:
                «Я не могу написать этот код без создания моков и нарушения инкапсуляции.
                Что мне делать?»
                Один мастер программист ответил:
                «Моки — это плохо, и ты никогда не должен нарушать инкапсуляцию.
                Перепиши код, чтобы можно было тестировать правильно.»
                Другой мастер ответил:
                «Моки — это хорошо, и тестирование важнее инкапсуляции.»
                Обескураженный ученик ушел за пивом. В местной пивной он встретил
                Величайшего мастера программиста посасывающего пивко с куриными крылышками.
                «Величайший мастер!» — сказал ученик, — «Я думал, что вы не пьете.
                И разве вы не вегетарианец?»
                Величайший мастер улыбнулся и ответил:
                «Иногда жажда лучше утоляется пивом, а голод — куриными крылышками».
                Ученик больше не был обескуражен.
                • НЛО прилетело и опубликовало эту надпись здесь
                  • 0
                    Я сейчас читаю Макконела «Совершеннй код». Я прекрасно понимаю, что качественный код выгоднее, чем, написанной кое-как. И я ни в коем случае не считаю, что решения, о которых мы спорим, написаны кое-как. Но если Вы можете написать лучше, сохранив простоту использования без значительного увеличения объёма кода — будьте добры, покажите пример. Только не надо общих слов, про передачу аргументов через конструктор. В заметке есть простой пример использования библиотеки. Перепишите этот пример так, как на Ваш взгляд, он должен выглядеть, по Вашим представлениям. Я всегда готов учиться и совершенствоваться.
                  • +1
                    Евгений, зачем преумножать сущности сверх необходимого? Вы говорите, безусловно, правильные вещи, но в каком-то догматическом ключе. Из комментария в комментарий, как мантры. Постоянно ссылаясь на SOLID и GRASP Вы, почему-то, совершенно забываете про KISS и YAGNI. Почему?

                    К примеру, я фанатично использую Prepared Statements. Я вижу в этом смысл и выгоду. Даже в «наколеночных» скриптах. А наворачивать пару-тройку слоев абстракции при любом удобном случае, подключить Dependency Injection Container, обложить все неймспейсами и т.д. я не буду. Мне кажется это избыточным. А вам?

                    Напишите уже наконец статью, в которой опишите букет приемуществ вышеописанных Вами практик. Я бы с удовольствием прочел.

                    А так, Вы безапеляционно предаете анафеме все что содержит глобалсы, инклуды, статик и т.д. Может от bool тоже отказаться? Вон пилят уже теплый ламповый ООПешный bool.
                    • НЛО прилетело и опубликовало эту надпись здесь
                      • 0
                        Читать не лень. Этим и занимаюсь. Но не всегда и не все бывает понятно. Я не слишком обогащен опытом, наверное поэтому так. Вы бы изложили доходчиво с примерами Ваши мысли. Все равно каждый раз в комментариях битва с Вашим участием.

                        Я, например, искренне заинтересован в углублении своих знаний и навыков, но т.к. я, возможно, уступаю Вам по уровню знаний, мне многие Ваши примеры и кажутся моструозными и излешне абстрагироваными. Я, например, говорю Вам о том, что «Вы усложняете...», Вы вешаете на меня (в уме) ярлык «недалекого быдлокодера» и все. Вот и поговорили, называется.
  • 0
    дилей это конечно хорошо, но что мешает боту сделать таймаут на заполнение полей?
  • 0
    Поля-примнаки стоило бы поправить
    • 0
      Спасибо, поправил.
  • 0
    Я скрыл от пользователей у себя поле email. Боты его заполняют все; пользователи — никто. Уже давно система работает и не дает сбоев. Все просто. Да, специальных ботов под этот сайт не пишут.
  • –1
    Защищаю формы без всяких капчей и прочей хрени.
    Достаточно проявить смекалку.
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    > У каждого найденного поля имя меняется на сгенерированную случайным образом комбинацию символов и создаётся скрытое средствами CSS поле с оригинальным именем.

    Отличная идея спрятать название полей в какой нить md5 и сохранить его в сессию, а когда надо расшифровать обратно. У роботов реально нет никаких шансов.
    • 0
      У людей тоже, ведь мд5 обратно не расшифровывается.
      • 0
        Смотри перед созданием формы ты кладешь в $_SESSION ассоциативный массив name => md5.
        И преобразуешь название полей вот так:

        name => 7671651541726
        email => 8765673467392

        После приема формы на сервер ты обратно преобразуешь md5 => name.

        7671651541726 => name
        8765673467392 => email

        Вот и весь метод ;)
        • 0
          Я плохо знаю PHP. Вы предлагаете на сервере в явном виде хранить соответствие между настоящими и переделанными именами полей? И потом восстанавливать их из этих данных, если не завершена сессия? Что мешает боту инициировать новую сессию и повторить все эти действия?
          • 0
            Как вы предлагаете заполнить боту следующие поля:

            Какими значениями? Потом если вы уж такой педантичный и думаете ориентироваться на местоположение поля ввода — добавьте эффект случайности ;) Меняйте местами поля ввода.
            Думаю, что тут уже точно надо будет посидеть над написанием бота для вашего сайта. А
            если еще и добавить скрытые поля, то проблема решена… Или таки кто-то придумал как взломать
            такого бота?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.