AdGuard MV3 — первый блокировщик рекламы на основе Manifest V3

2022-08-30 13560 комментарии
Новое экспериментальное браузерное расширение AdGuard MV3 уже доступно для скачивания в Интернет-магазине Chrome

Manifest V3, новый API расширений Chrome, постепенно становится новой реальностью, в которой будут работать десятки расширений для блокировки рекламы и отслеживания, включая расширение AdGuard.

Изменения Manifest V3 оказались неизбежными. Когда в 2018 году Google впервые опубликовал документ с описанием нового API, сообщество разработчиков подвергли его острой критике. Разработчики Adguard также не стали молчать и даже подготовили отдельные материалы о возможных негативных последствиях реализации Manifest V3 и о их собственном отношении к данным изменениям.

Несмотря на публичное негодование, Manifest V3 был представлен в Chrome 88 Beta в конце 2020 года. С января 2022 года разработчики больше не могли размещать в Интернет-магазине Chrome расширения, работающие на Manifest V2. А скоро пройдет финальная стадия запуска: в январе 2023 года все расширения на Manifest V2 прекратят свою работу, причем даже те, которые были ранее добавлены в Интернет-магазин Chrome.

Примечание: Если вы пользуетесь десктопными приложениями AdGuard для Windows и Mac или мобильным приложением для Android, то вам не стоит беспокоиться об изменениях Manifest V3. Браузерные ограничения не затрагивают эти продукты.

Экспериментальное расширение AdGuard MV3

В середине 2021 года разработчики AdGuard приступили к созданию прототипа нового расширения, который бы смог эффективно блокировать рекламу в условиях строгих ограничений Manifest V3. Задача была не из легких: новый API был еще сыроват, некоторые аспекты еще дорабатывались, и некоторые вещи работали не так, как было задумано. Однако, команде AdGuard удалось выполнить задачу и подтвердить, что блокировщики рекламы смогут выжить даже после апокалипсиса, вызванного Manifest V3.

Во время разработки прототипа разработчики столкнулись с серьезными проблемами, вызванными функциями нового API. Некоторые из них удалось решить, а под некоторые пришлось подстроиться.

Новое экспериментальное браузерное расширение AdGuard MV3 уже доступно для скачивания в Интернет-магазине Chrome.

Скачать AdGuard MV3

На следующем видео продемонстрирована работа расширения:

Ограничения на количество правил

Примечание: Если вы не знакомы с правила фильтрации контента и с тем, как в целом работает блокировка рекламы, то можете ознакомиться с базой знаний AdGuard.

В рамках Manifest V3 все правила в составе фильтра расширения были разделены на статические (встроенные) и динамические, и их количество было значительно сокращено.

Manifest V3 позволяет расширению использовать до 30000 статических правил с общим ограничением на все расширения, установленные одним пользователем — 330000 правил (сюда входит ограничение в 1000 правил с регулярными ограничениями на одно расширение). Нюанс заключается в том, что весь доступный объем может получить одно или несколько расширений, а для остальным расширениям просто не хватит лимита.

Если это произойдет с расширением AdGuard (причем это может произойти в любое время после обновления, перезапуска сервис-воркера, изменения набора фильтров в расширении AdGuard или в стороннем расширении), то появится сообщение о том, что браузер изменил список активных фильтров и оставил включенным только базовый рекламный фильтр AdGuard. В самом худшем сценарии даже базовый фильтр может так и не включиться, если он содержит более 30000 правил. В результате пользователь останется без защиты AdGuard.

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

Что касается динамических правил, с помощью которых пользователи могут добавлять собственные правила и фильтры, то для них установлен мизерный лимит в 5000 правил, включая лимит в 1000 правил с регулярными выражениями. При превышении данного лимита AdGuard MV3 сможет применить только первые 5000 правил, а остальные не будут браться в расчет.

Уведомления о превышении лимита будут выглядеть следующим образом:

Ограничения Manifest V3 негативно влияют не только на качество фильтрации и пользовательский опыт, но и на сообщество разработчиков фильтров. Раньше каждый мог создавать фильтр только под себя, но потом этот фильтр мог становится популярным и даже попасть в список рекомендованных в блокировках. Теперь этого будет сложнее добиться. В конце концов, блокировщики должны использовать предустановленные фильтры (не более 50), поэтому нужно очень избирательно подходить к подбору доступных для пользователей фильтров. Конечно, вы по-прежнему сможете вручную настраивать фильтры. Но не стоит забывать про ограничение в 5000 правил для всех пользовательских фильтров и правил.

Ниже приводится описание проблем, с которыми столкнулись разработчики AdGuard MV3, с большим количеством технических подробностей, которые будут понятны в основном разработчикам. Рядовым пользователям лучше сразу перейти к заключению.

Декларативные правила

Еще до запуска Manifest V3, движок фильтрации создавался динамически из фильтров, загруженных расширением с удаленного сервера. При этом правила в составе фильтров применялись на разных стадиях загрузки веб-страницы.

Например, правила могли срабатывать, пока браузер еще не отправил запрос: по событию onBeforeRequest браузер спрашивал у расширения, что нужно сделать с конкретным запросом, а расширение динамически реагировало блокировкой или перенаправлением. Косметические правила применялись позже, после того как страница была загружена и появилось DOM-дерево.

С внедрением Manifest V3 метод onBeforeRequest больше нельзя использовать. В качестве альтернативы Google предлагает использовать declarativeNetRequest API, который позволяет изменять передаваемые браузеру запросу. Расширение задает набор декларативных правил, в соответствии с которыми бразер будет изменять или блокировать сетевые запросы.

Синтаксис декларативных правил

Синтаксис декларативных правил отличается от общепринятого синтаксиса современных блокировщиков рекламы. Большинство участников сообщества откажутся от разработке правил на основе Manifest V3, потом что они заточены исключительно под Chrome.

Каждое правило должно иметь следующие поля:

  • id — идентификатор правила. Идентификатор можно использовать для привязки декларативного правила к текстовому правилу.
  • priority – приоритет правила. Определяет, в каком порядке правило будет применяться к запросу.
  • action – действие правила.

действия бывают трех видов:

    • block — блокировка запросов
    • redirect или upgradeScheme — перенаправление запросов.
    • allow или allowAllRequests — действия, разрешающие запросы.
  • condition – условие, при котором применяется правило

Пример правила:

{

  "id": 1,

  "priority": 1,

  "action": { "type" : "block" },

  "condition": {

    "urlFilter": "abc",

    "domains": ["example.org"],

    "resourceTypes": ["script"]

  }

}

Данное правило будет блокировать все запросы к скриптам с домена example.org, у которых в адресе есть подстрока abc

С аналогичной ситуацией разработчики AdGuard сталкивались при создании расширения блокировки рекламы для Safari. Тогда им приходилось находить способ конвертации правил в синтаксис, предложенный разработчиками браузера. На этот раз аналогичное решение используется для преобразования собственного синтаксиса в декларативные правила Chrome.

Для конвертации статических и динамических правил в библиотеку @adguard/tsurlfilter был добавлен новый модуль. Библиотека перебирает правила фильтров и преобразовывает их в декларативные правила, а затем объединяет их в наборы правил и сохраняет в файлы .json. Связи между текстовыми правилами и правила JSON не теряются, благодаря использованию таблицы соответствия.

Приведем пару примеров работы библиотеки:

Правило ||example.com^$script будет преобразовано в:

{

    "id": 1,

    "action": {

        "type": "block"

    },

    "condition": {

        "urlFilter": "||example.com^",

        "resourceTypes": [

            "script"

        ],

        "isUrlFilterCaseSensitive": false

    }

}

Правило @@||example.com^$script$domain=example.org будет преобразовано в:

{

    "priority": 1,

    "id": 23,

    "action": {

        "type": "allow"

    },

    "condition": {

        "urlFilter": "||example.com^$script",

        "initiatorDomains": [

            "example.org"

        ],

        "isUrlFilterCaseSensitive": false

    }

}

Большинство правил конвертируются корректно, но часть функциональности теряется из-за различных ограничений:

  • $removeparam не поддерживает исключения (~) и регулярные выражения (regexp)
  • Для регулярных выражений в Chrome используется собственная реализация, поэтому часть стандартной функциональности не поддерживается, например  регулярные выражения, содержащие обратные ссылки, отрицательный поиск вперед (negative lookahead) и квантификаторы.
  • negative lookahead часто используется фильтрах. При быстром поиске в фильтрах AdGuard было найдено 43 таких правила. Кажется, что это небольшое число, но на самом деле большинство правил работают на многих доменах. Таким образом, всего одно ограничение мешает работе блокировщика на более чем 1000 сайтов.
  • Регулярные выражения дополнительно проверяются Chrome на предмет количества потребляемой памяти. Точная реализация неизвестна, поэтому могут возникать проблемы с регулярными выражениями.
  • Cookie-правила не поддерживаются.
  • Существуют и другие проблемы, которые здесь не упоминаются.

Недостаток декларативных правил очевиден: их синтаксис ограничивает функциональные возможности расширения. С этим ничего нельзя поделать — остается надеяться, что разработчики Chrome со временем это улучшат.

Наборы правил

Согласно новому API, декларативные правила можно объединять в наборы правил.

Приведем пример интеграции набора правил в Manifest V3:

{

  "name": "AdGuard AdBlocker MV3",

  "version": "1",

  "declarative_net_request": {

     "rule_resources": [{

       "id": "ruleset_1",

       "enabled": true,

       "path": "rules.json"

     }]

   },

   …

}

Наборы правил указываются в файле manifest.json и загружаются только при установке или обновлении расширения. И это тоже огромная проблема. Иногда правило фильтрации нарушает структуру или быстродействие одного или нескольких сайтов. При таком невероятно большом количестве правил статистически невозможно полностью избежать подобных инцидентов. Кроме того, сайты постоянно меняются, и правила, которые раньше работали корректно, теперь могут вызывать ошибки. В свое время команда Adguard нашла простое решение этой проблемы.

Представим, что проблемное правило находится в фильтре, и его нужно быстро отключить. В расширении на основе Manifest V2 для этой цели использовался модификатор $badfilter. Разработчики фильтров добавляли правило с указанным модификатором, расширение динамически обновлялось и новое правило отключало указанное правило. Понятно, что с Manifest V3 этот «трюк» не пройдет.

С внедрением Manifest V3 можно ожидать, что фильтры не будут обновляться несколько дней подряд: после добавления новой версии в Интернет-магазин Chrome нужно дождаться прохождения проверки. К сожалению, нет другого способа предоставить пользователям обновленные фильтры. Дискуссия о возможности включать и отключать отдельные правила дает некоторую надежду. Сохраняется небольшой шанс, что расширения все-таки получат возможность быстро обновлять фильтры.

Статистика и журнал фильтрации

Браузерное расширение AdGuard на базе Manifest V2 имеет журнал фильтрации, в котором отображаются все запросы, отправляемые браузером, и подробная информация о них. В частности, вы можете увидеть, какое правило фильтрации использовалось для блокировки того или иного правила.

Теперь же Chrome сам блокирует запросы и делится статистикой только с расширениями, разархивированными и установленными в режиме разработчик. В таких условиях реализовать журнал фильтрации, как раньше, не получиться. Однако, в финальной версии расширения будет предложена альтернатива.

При открытии журнала фильтрации будет запущен движок, работающий по правилам Manifest V2. Он не сможет взаимодействовать с запросами, зато покажет, какие правила могли быть применены. Сравнив статистику Chrome с результатами старого движка можно получить примерное представление о том, как обрабатываются запросы.

Текущая версия прототипа не имеет журнала фильтрации. Вместо этого разработчикам фильтров придется использовать механизм, рекомендованный разработчиками Chrome. Интересно, что пользователи все же смогут получить информацию о том, какое правило сработало, но для этого расширение нужно будет устанавливать в «распакованном» виде. То есть вам нужно будет клонировать репозиторий AdGuard, выполнить сборку расширения, переключить браузер в режим разработчика, и только в этом случае вы сможете использовать инструменты для отладки фильтров.

Сервис-воркеры

В Manifest V3 исчезла фоновая страница. Фоновая страница — это отдельный фоновый процесс, в котором расширения могут сохранять свое состояние и работать с API-интерфейсами браузера. В Manifest V3 эта страница заменена сервис-воркером (Service worker), который часто прерывается браузером.

Когда браузер останавливает сервис-воркер, расширение переходит в своеобразный спящий режим: декларативные правила работают, а косметические правила, загружаемые динамически — нет. Чтобы расширение заработало, что-то должно разбудить сервис-воркера: это может быть загрузка страницы или сообщение, отправленное сервис-воркеру.

Когда сервис-воркер возвращается к работе, расширение начинает считывать правила фильтрации из репозитория и обрабатывать их, чтобы затем быстро их найти. За это время в течение 1,5-2 секунд расширение не применяет косметическую фильтрацию, но рекламные запросы блокируются самим браузером. Затем запускается движок, и реклама исчезает. Разработчики AdGuard планируют сократить время пробуждения сервис-воркера и стремятся перенести большую часть косметических правил в контент-скрипт (который работает в контексте веб-страницы и не выключается каждую минуту).

Заключение

Несмотря на ограничения Manifest V3, AdGuard MV3 по-прежнему неплохо защищает от рекламы и отслеживания:

  • Проактивно блокирует запросы отслеживания
  • Скрывает баннеры, виджеты социальных сетей и другие нежелательные элементы веб-страницы
  • Блокирует рекламу в видеосервисах, включая YouTube

Хотя экспериментальное расширение не так эффективно, как расширение на Manifest V2, большинство пользователей не почувствуют разницы. Единственное, что вы можете заметить — это мерцание рекламы из-за задержки в применении косметических правил.

Цель данного прототипа — протестировать новый подход и получить отзывы пользователей. Расширение имеет открытый исходный код, опубликованный на Github. О проблемах и предложениях можно сообщать там же, на Github.

Экспериментальная версия AdGuard MV3 вышла 30 августа 2022 года и стала первой среди разработчиков блокировщиков рекламы. Команде AdGuard предстоит еще много работы, но уже можно утверждать, что даже после прекращения поддержки Manifest V2 пользователи Google Chrome смогут защитить себя от рекламы и трекеров с помощью браузерного расширения AdGuard.

© . По материалам AdGuard

Комментарии и отзывы

Добавляя комментарий, ознакомьтесь с Правилами сообщества

Нашли ошибку?