Ввиду того, что мы не можем раскрывать данные клиентов, мы удалили с изображений ниже часть данных, но поверьте, что для понимания масштаба кликфрода, это будет не критично. Плюс мы перед публикацией на этом сайте выждали несколько месяцев (перестраховались, данные собирались летом 2021).
Посмотрите на изображение ниже (можно увеличить по клику). Это фрагмент из нашей внутренней базы данных (мы используем MS SQL), где фиксируются все визиты пользователей на сайты.
![](https://habrastorage.org/getpro/habr/upload_files/855/24b/af1/85524baf1a05f67c4df7beece98ea53e.png)
Что тут видно? На сайт клиента было сделано 3 захода (визита) с одного IP- адреса (вот этот адрес 178.214.248.145) в один день (8 июня 2021 года). При этом каждый визит пользователя содержал одно действие (Actions, по сути один клик) и длительность первых двух визитов была порядка 6 секунд, третий 22 секунды (все визиты довольно короткие). Источник определялся как город Уфа, оператор связи ufanet.ru. Все эти три визита были сделаны по контекстной рекламе Яндекс.Директ (поле referrername, видны utm метки, частично мы их удалили для конфиденциальности).
Почему именно это привлекло наше внимание и легло в основу публикации? Дело в том, что наша система защиты от скликивания считает цифровой "отпечаток" браузера, с которого был выполнен заход. И в данном случае он одинаковый (поле FingerPrint на изображении выше). Вот он:
48e3923c1519e3ac85e4859b542c13c5
Чуть отвлекусь - для сбора данных с сайтов мы используем matomo и я смело могу рекомендовать систему. Работает очень стабильно (сейчас мы анализируем до 100к визитов в сутки с более чем 170 сайтов и все это спокойно работает на одном сервере bare metal), обновления выходят регулярно, есть API. Код мы ставим на сайты клиентов с помощью GTM, включая расчет fingerprint.
Возвращаясь к "отпечатку". Если говорить сильно упрощенно, то цифровой "отпечаток" браузера — это механизм, используемый для отслеживания уникальности посетителей. Посетителям присваивается уникальный идентификатор ("отпечаток", последовательность цифр и символов).
Согласно исследованиям, уникальность "отпечатка" браузера довольно высока. Если говорить о публично доступной статистике, то только раз на ~300 000 случаев случается полное совпадение "отпечатков" браузеров двух разных пользователей. Исходя из этого, можно с высокой вероятностью предположить, что по рекламе, в рассматриваемом случае, кликал один и тот же пользователь (дальше будем называть его бот, хотя допускаем, что это был человек, которые вручную сидел и скликивал рекламу).
Могу смело рекомендовать авторскую работу по этой ссылке ("We’ve analysed 500,000 browser fingerprints. Here is what we found." Peter Hraška), где как раз проводился анализ уникальности "отпечатков" в разных средах. В Интернете вы можете легко найти готовые бесплатные и условно бесплатные библиотеки расчета "отпечатка". Посмотрите, пожалуйста, информацию по этой ссылке ("Canvas fingerprinting on the web" Antoine Vastel - кстати, много материала у этого автора по обнаружению ботов, могу рекомендовать).
Есть ли способы генерировать на каждый визит уникальный «отпечаток» браузера? Да, но существует несколько ограничивающих факторов. Первый — не может быть бесконечное количество уникальных "отпечатков" даже при их генерации (иными словами всегда будет выборка из некой базы, конечное число - посмотрите например вот тут упоминают базу из 50к готовых "отпечатков" и это, кстати, платное решение), второе — это требует уже определенных усилий и знаний от кликера. Если вы посмотрите как работают программы по скликиванию то заметите, что это далеко не rocket science (ниже видео с YouTube, если редакция Хабра оставит, то многое станет понятно - сразу скажу, это 100% мошенничество и кстати уголовно наказуемое, если поймают). Есть расширения для браузеров, которые позволяют подделывать "отпечаток", но при их обнаружении можно сразу вывешивать «красный флаг», т.к. 99% обычных пользователей вашего сайта эти расширения не нужны.
Есть ряд исследований, который подтверждают, что самые обычные действия, которые приходят «на ум» для смены отпечатка браузера, не сильно помогут:
1. Файлы cookie: генерация "отпечатков" браузера не полагается на файлы cookie для создания уникального идентификатора. Таким образом, хотя их отключение может обеспечить некоторую степень конфиденциальности бота, оно не влияет на возможности получения "отпечатков".
2. Режим Инкогнито: этот метод неэффективен для предотвращения получения "отпечатков" браузера, так как доступны другие параметры, помимо истории просмотров, которые могут использоваться для идентификации.
Кому любопытно, может посмотреть вот это исследование (Detecting incognito mode in Chrome 76 with a timing attack), которое демонстрирует возможности определения режима Инкогнито (русский перевод доступен по этой ссылке). Согласитесь, очень странно, если вдруг пользователь будет кликать по рекламе и заходить на сайт в режиме Инкогнито.
3. VPN подключение эффективно для сокрытия истории просмотров посетителя или сокрытия реального IP -адреса и геолокации пользователя. Однако это не очень эффективно для предотвращения получения "отпечатков", поскольку многие скрипты для их генерации не используют IP-адрес в качестве основного источника.
Есть несколько механизмов усложнения снятия "отпечатков", но и они не являются надежными. Некоторые браузеры предлагают встроенные функции; например, Firefox дает пользователям возможность блокировать сторонние запросы к сайтам, которые генерируют "отпечатки". Другой возможный способ уменьшить количество доступных источников — полностью отключить функциональные возможности, такие как canvas HTML или аудиоконтент, которые обычно используются для генерации «отпечатков». Однако многие сайты не будут правильно загружаться без этих технологий, и это позволит быстрее выявить бота.
Возвращаемся к анализу, что получается? Бот в этот день кликнул три раза на рекламу в Яндекс.Директ, у него был в каждом случае один IP — адрес, один "отпечаток" браузера и… разные Яндекс.ClientID (поле YandexClientID на изображении выше). Обратите внимание на поле reCaptchaOdd с значением 0.1, я чуть позже вернусь к этому, т.к. данное значение на 99% подтверждает наше подозрение, что это бот.
Что такое Яндекс.ClientID?
ClientID — это идентификатор, который Яндекс.Метрика автоматически присваивает каждому уникальному посетителю сайта. Идентификатор создается по сути случайным образом и определяет браузер, в котором посетитель просматривает ваш сайт. Если бот заходил на один и тот же сайт, например, с помощью Google Chrome и Opera, в Яндекс.Метрике будет зафиксировано два разных ClientID. ClientID дает вам возможность различать и узнавать уникальных посетителей, собирать их действия на сайте в сессию и связывать между собой данные о сессиях, произошедших в разное время.
Яндекс.Метрике ClientID выглядит следующим образом: _ym_uid=1573226534123620835
_ym_uid — название cookie, первые десять цифр — время создания cookie в формате UNIX, а вторые десять цифр — число, сгенерированное случайным образом.
В нашем случае Яндекс.Метрика выдавала каждый раз разные ClientID одному пользователю-боту. Почему так? Чтобы ответить на этот вопрос, мы провели простой эксперимент и вы можете легко повторить его сами. Наш сотрудник зашел на один и тот же сайт напрямую три раза с одного ПК (рабочий ПК). Первые два раза он зашел с одного браузера с интервалом в один час, третий раз — он открыл сайт с браузером в режиме «Инкогнито» (обратите внимание, что "отпечатки" одинаковые, так и должно быть - ведь пользователь, по сути, один).
![](https://habrastorage.org/getpro/habr/upload_files/5af/830/708/5af830708f5fdcaec63413f27e5c53c6.png)
Яндекс.Метрика корректно определила второй заход (мы специально выждали час, чтобы закрыть сессию) и присвоила одинаковые ClientID. А в третий раз (13.43), из-за режима «Инкогнито», был сгенерирован новый ClientID и для Яндекс.Метрика это по сути новый пользователь.
Кстати, Яндекс.Метрика формирует глобальный ClientID привязанный к браузеру, а не домену сайта и это (теоретически, мы не проверяли) позволяет видеть историю посещений пользователей по вашим разным сайтам, если на них установлен один счетчик Яндекс.Метрика. Есть еще нюанс в том, что сколько хранится файл cookie от Яндекс.Метрика? Ранее он хранился два года с момента последнего визита или период, установленный в настройках браузера пользователя. Сейчас некоторые браузеры стали ограничивать срок жизни cookie и, например, Apple Safari хранит только две недели, независимо от настроек сайта. В итоге, если посетитель зашел на сайт с разницей больше 2-х недель, то для системы аналитики это уже два разных пользователя, так как при втором посещении старого cookie уже нет и браузер записал новый файл. В нашем эксперименте выше, в режиме Инкогнито, cookie файл не сохранился и Яндекс.Метрика сформировала новый ClientID.
Возвращаясь к кейсу выше. С очень высокой вероятностью можно предположить, что скликивание осуществлялось каждый раз с очисткой cookie браузера, чтобы Яндекс.Метрика вновь идентифицировала пользователя как нового и соответственно присваивала новые clientID. Зачем? Чтобы данные клики учитывались как действительные и средства с бюджета Яндекс.Директ клиента списывались. По этому же принципу работают простые программы для скликивания (видео выше).
Давайте посмотрим, как часто пользователь с указанным "отпечатком" заходил на данный сайт вообще (по рекламе и нет). Посмотрите на изображение ниже. Это данные за один день. Видно, что заходы происходят постоянно.
![](https://habrastorage.org/getpro/habr/upload_files/26b/4ad/aa4/26b4adaa48a61d91747ce079a1e4ba33.png)
Какие характеристики у всех этих визитов? Всегда одно действие (клик), 3-5 секунд на сайте и разные IP- адреса. Обратите внимание, что в некоторых случаях Яндекс не присвоил клиенту ClientID. Это может быть в нескольких случаях. Первый — бот слишком быстро ушел с сайта и счетчик Яндекс.Метрика просто не запустился, второй — Яндекс сам определил визит как бота и посчитал клик «недействительным». К сожалению, таких визитов не много. В основном каждый визит получает новый ClientID, при одинаковом "отпечатке".
Прошу, не пишите в комментариях, что Яндекс сам скликивает рекламу :). Ровно как и то, что Яндекс совсем не борется с ботами. мол "пчелы против меда..". Просто основная задача Яндекса — продажа рекламы, в не борьба с кликфродом. Если посмотреть на Google то, несмотря на его колоссальные возможности, процветают сторонние сервисы, которые обеспечивают дополнительную защиту. Кстати, Яндекс совершенно недавно анонсировал новый алгоритм определения недействительных кликов.
Как бот менял свой IP- адрес? Скорее всего он использовал прокси- сервера. Не буду писать детально что такое прокси, информации масса. Сейчас важно понимать, что все клики были по рекламе (тип источника campaign, что означает любой «платный источник» в классификации matomo). Очевидно, что имеет место быть активное скликивание рекламы.
Как часто этот бот менял IP- адреса при кликах на рекламу сайта? Мы сделали простую выборку, см. изображение ниже. Видно, что каждый IP- адрес использовался несколько раз (Visitcount) и легко заметить, что некоторые IP- адреса явно брались с одного пула (например 176.222.*.* или 176.214.*.*). Не так уж сложно купить пул адресов.
![](https://habrastorage.org/getpro/habr/upload_files/54c/539/dac/54c539dacf84f4af9e54b2aaf5d3d132.png)
Почему мы вообще решили, что это бот? Дело в том, что в своей защиты мы используем несколько алгоритмов, которые работают последовательно, шаг за шагом идентифицируя ботов. В самих алгоритмах нет секретов, вы можете повторить их на своем сайте при наличии программистов. Например, мы проверяем вхождение IP- адреса в «черные» списки (вот, например, один из возможных источников).
Если мы возьмем адрес 178.214.248.145 (см. изображение выше — это адрес бота), то можно легко проверить его на чистоту с помощью любого сервиса. Вы можете сделать это сами, перейдя по ссылке: https://dnschecker.org/ip-blacklist-checker.ph? query=178.214.248.145 (учтите, что через некоторое время адрес может уйти из черных списков, поэтому важно делать проверку оперативно). Данный адрес был найден в нескольких списках.
Что мы сделали еще? Проверили визит с помощью Google reCaptcha v3 (невидимая), чтобы получить дополнительную оценку качества сессии. Если мы вернемся на изображения выше, то увидим, что для всех упомянутых визитов ботов коэффициент reCapcha был равен 0.1 (очень высоко вероятно это бот в терминологии Google), а визит нашего сотрудника, при проверке расчета Яндекс.ClientID, дал коэффициент 0.9 (очень высоко вероятно это человек - это так и было :). Следом у нас работает алгоритм машинного обучения (если быть конкретнее, алгоритм К-ближайшее), который кластеризует все визиты, чтобы находить тех ботов, который стараются мимикрировать под обычных пользователей.
Возвращаясь к поведению данного скликивающего бота. Мы посчитали, сколько раз вообще данный бот менял свое окружение так, что Яндекс.Метрика определяла его каждый раз как нового — 462 раза.
![](https://habrastorage.org/getpro/habr/upload_files/64e/675/cde/64e675cde97d57a8be01b8b6944fe701.png)
Почему мы решили, что это точно бот, ведь наверняка сказать невозможно? Это так, никогда нет абсолютно точной вероятности, что мы заблокировали именно бота. Но мы можем судить по подмене ClientID, по одинаковому цифровому «отпечатку» (который вкупе с другими данными только подтверждает нашу гипотезу). Такое поведение не похоже на действие реального пользователя. Также, чтобы убедиться, можно дополнительно посмотреть через Вебвизор в Яндекс.Метрика — часто действия ботов отличаются однообразием и линейностью движений мышкой, в то время как у реального пользователя они более хаотичны, но применительно к конкретному сайту, учитывая его навигацию. Не все готовы предоставить доступ к Вебвизору нашим аналитикам, поэтому приходится полагаться на те данные, которые мы собираем сами в представленных в этом обзоре таблицах. Кстати, анализ движения мышки очень интересный подход к выявлению ботов и я рекомендую интересующимся ознакомиться с работой по этой ссылке ("CLUSTERING WEB USERS BY MOUSE MOVEMENT TO DETECT BOTS AND BOTNET ATTACKS", San Luis Obispo).
Данный клиент подключился к нам 2 июня 2021 с просьбой проверить есть ли у него скликивание (обычно рекламные агентства ссылаются на то, что Яндекс/Google возвращают деньги за недействительные клики и беспокоится не нужно). За 8 первых дней июня было сделано порядка 462 клика по рекламе. Мы не знаем стоимость одного клика, предложим, что она находится в пределах 50 руб. (не так уж и много).
К сожалению, у нас нет доступа к Яндекс.Метрика/Яндекс.Директ, чтобы точно проверить какое количество кликов было признано Яндексом как недействительные, но из нашего опыта анализа других клиентов знаем, что при наличии Яндекс.ClientID в 80-90% случаев клики засчитываются как действительные и деньги списываются. Нехитрая математика дает нам оценку потерь: 8 дней, 462 кликов * 50 руб. = 23 100 руб. (не стал делать поправку на 80% вероятности засчитать клики, т.к. предложенная стоимость клика в 50 руб. кажется не очень высокой для сферы деятельности бизнеса).
Ну вот как-то так...В заключении даже и не знаю, что написать. С скликивающими ботами бесконечная борьба - они пытаются обхитрить механизмы защиты Яндекс/Google и мимикрировать под обычных пользователей, а мы их пытаемся вычислить разными методами. Борьба "брони" и "снаряда". Данный бот, после блокировки, не возвращался. Хотя, разумеется, он мог пройти процедуру "реинкарнации" путем смены "отпечатка".