https://habrahabr.ru/post/340562/- Разработка веб-сайтов
- JavaScript
- Google Chrome
Немного пятничный пост. В последнее время заметил что есть реклама которая пробивает сразу 2(!) расширения блокирующие её. И обычно это очень низкокачественная и навязчивая реклама. Решил разобраться как так, и, возможно, даже попробовать побороть эту дрянь. Кому интересно — прошу под кат (осторожно, много картинок).
А чем мешает то?
Я — ярый сторонник блокировки рекламы. Особенно — низкокачественной. Если я не хочу смотреть рекламу на определённом сайте — то такая реклама это деньги на ветер для рекламодателя (бесполезный показ), неуважение ко мне, и нулевой профит вообще для кого либо. Оговорюсь сразу — есть сайты на которых я сознательно вырубаю адблоки (тот же хабр, например). Это сайты которые выбирают тематическую рекламу, а не «АЙФОНЫ СО СКЛАДА 70% СКИДКА!».
И тут на днях на одном дружественном мне сайте (новостной портал в моём городе) появляется ну ооочень низкопробная реклама в стиле «электрики долго скрывали — чтобы экономить электричество надо всего лишь...». Сначала я подумал что их взломали, но потом оказалось что админ этого сайта просто ввязался в какую-то партнёрку которая работает поверх адблока. И мало того что такая реклама это просто стыд, так она ещё и ломала местами вёрстку. Закрыть её стало делом принципа.
Попытка 1 — в тупую, или...
… «пфф, да ща напишу кастомный фильтр для адблока». Пишем фильтр, сохраняем, тестим… А страница то ломается, прям совсем. И косметические фильтры (блокировка по css) тоже не работают. Как так? Но, видимо, поэтому и не было такого фильтра «из коробки». Как окажется позже — наш «зловред» хитрый и заинлайнен, а хромообразные браузеры не позволяют расширениям блокировать инлайновые скрипты. Ну и ну…
Попытка 2 — меняем адблок
Слово «адблок» уже давно стало нарицательным, как джип или ксерокс. Так что на самом деле у меня стоит не adblock а ublock (надеюсь это не сочтут за рекламу?). Поэтому для начала тестим работу разных блокировщиков из топа выдачи, которые обещали скрываться от хитрозадых скриптов, и блокировать даже их. Выхлопа, на самом деле, это не дало, и часть рекламы продолжала пролезать (хотя и не вся, но всё же).
Попытка 3 — смотрим врагу в глаза
И нет, я не имею ввиду админа ресурса :) Приступим к самому интересному. Лезем смотреть исходники страницы, в надежде найти нашу гадость. И… Бинго!
Огромная обфусцированная кодина, которая явно тут не спроста. Смотрим похожие сайты (в плане рекламы) — да, это явно оно. И обфусцировано добротно, не банальным p.a.c.k.e.r-ом.
Немного распакуем, чтобы понять где зарыта собака. Если присмотреться на монстра, можно заметить что это самовызывающаяся функция, внутри которой есть три основные части — большая функция, какой-то массив с числами и небольшой обработкой его же, и вызов первой функции. Скопируем массив и его обработку, запускаем, смотрим вывод.
Переменная «а» у нас хранит весь набор слов которые нельзя было заменить на однобуквенные. А в первой части мы видим много фрагментов вида а[42], a[69], и т.д. Обфускация оказалась не такой уж и сложной. Делаем замену которая не гарантирует нам работающий код, но сильно облегчит чтение.
Уже видно более-менее читаемый код. Пропускаем через beautifier, и находим желаемый участок кода (я удалил неважный код чтобы поместиться в одном скрине).
Эта зараза делает запрос на определённый юрл, и в случае отвала (попадания в фильтр адблока, например) — вызывает window.stop(), чем ломает всю страницу. Довольно хитро, и встроенным функционалом адблока это, вроде, не решаемо. А заблокировать весь скрипт не позволяет хром, ибо инлайн.
Что же делать?
После некоторых раздумий, у меня получилось расширение для браузера (ещё одно, да-да) которое занимается чисто блокировкой этой рекламы. Пока что оно заточено именно на эту сеть, потому как других я не знаю. Если кто захочет — форкайте, кидайте пулл реквесты, или отпишитесь в комментах — добавлю поле для добавления своих адресов.
Работает оно следующим образом — перехватываем запрос на «проверочный» адрес, с помощью
жёлудей и спичек элегантного костыля задерживаем его на 5 секунд, а в это время быстро-быстро отправляем сообщение на страницу. Страница принимает это сообщение, и тут же переопределяет window.stop на пустую функцию. Тем временем зловред таки получает отказ, ехидно улыбается, лупит по window.stop, и… ничего. Скрипт доволен (он уверен что всё сломал и пользователь таки отключит адблок), расширение довольно (потому что, как говорит мой коллега, на каждый хитрый зад найдётся хитрый мужской половой орган), пользователь (то есть — мы) доволен. Вероятно, в скором времени разработчики этой заразы что-то придумают и на это, но, пока-что, реклама успешно рубится.
Расширение заливать никуда не стал, ибо надо платный аккаунт, это proof-of-concept, сегодня пятница, и ещё 1000 и 1 малозначимая отмазка. Так что код на
гитхаб.
UPD. В комментариях возникли вопросы, поэтому тезисно о главном:
Почему не блокировать все инлайн скрипты — потому что это сломает логику многих сайтов, не подходит
Почему не возвращать 200 (обманывать) — потому что хром так не умеет. Либо 500ую, либо пропускаем
Почему не переопределять window.stop сходу — потому что надо успеть во временной отрезок когда DOM-блок head уже существует, но аякс ещё не вернулся. Это ограничение extensions API.