Детектирование установленных расширений Google Chrome

в 7:07, , рубрики: chrome, Extensions, Google, Google Chrome, браузеры, информационная безопасность, паранойя, расширения, метки: , , , , , ,

В конце февраля 2012 года разработчики Google Chrome существенно обновили черновую документацию по созданию расширений. В частности была предложена новая версия файла для описания внутренних ресурсов расширений — manifest version 2. И главной его особенностью стало ужесточение политики безопасности контента, по умолчанию.

Детектирование установленных расширений Google Chrome

Намедни же состоялся стабильный релиз долгожданного Google Chrome 18, и с этого момента разработчики расширений могут начинать внедрение произошедших изменений, ну а пока…

Как это работает?

Chrome Extensions, они же Apps, Приложения и Расширения — файлы *.CRX, это по сути простые ZIP-совместимые архивные контейнеры, внутри которых находятся типичные ресурсы веб-приложения: HTML и JS, картинки, иконки, а так же файлы всё это описывающие — manifest.json.

Для лучшего понимания нарушенной политики безопасности контента (Content Security Policy) в отношении расширений Google Chrome, приведу простой пример с вызовом картинки.

chrome-extension://aknpkdffaafgjchaibgeefbgmgeghloj/128.png

Вот к такому адресу обращается браузер, чтобы отобразить иконку установленного Chrome Angry Birds.
Разложим на составные части:

  1. chrome-extension://
    Это специальный псевдо-протокол, аналогичный http:// или file:///, но для общения внутренних файлов расширения между собой, и между самим браузером (есть ещё chrome:// но он нам не подходит).

  2. aknpkdffaafgjchaibgeefbgmgeghloj
    Каждое расширение в Google Chrome имеет свой уникальный идентификатор, который генерируется на этапе создания первой версии CRX-архива и происходящей в этот момент криптографической подписи архива RSA-ключом. То есть он перманентный, не изменяется от версии к версии, он будет одним и тем же для каждого клиента, установившего расширение из Chrome Web Store.

    Узнать ID любого установленного расширения можно через настройки Google Chrome:
    Settings → Extensions → Developer mode

    Или же на странице расширения из адресной строки:
    https:/chrome.google.com/webstore/detail/aknpkdffaafgjchaibgeefbgmgeghloj

    На худой конец можно зайти в папку профиля Google Chrome, например:
    %LOCALAPPDATA%GoogleChromeUser DataDefaultExtensions
    там то и лежат все расширения, распакованные, и с ID в качестве имени директории.

  3. /128.png
    Собственно, путь к файлу картинки, по которому она находится в директории расширения. Можно так же узнать из файл manifest.json.

И так, мы узнали каким образом расширение на подконтрольной себе странице вызывает иконку.

<img src="chrome-extension://aknpkdffaafgjchaibgeefbgmgeghloj/128.png" />


А теперь вопрос, что если вставить этот HTML-код в обычную страницу самого обычного сайта в интернете? Если в вашем гуглохроме установлен Angry Birds, то

[img] к сожалению, хабрапарсер не дал мне осуществить инлайн вылет птички :). Но надеюсь все всё поняли…

Далее на сцену вступает JavaScript — при помощи события onLoad скрипт проверяет картинку на «загруженность», таким образом и выявляется наличие у пользователя того или иного расширения, приложения, или даже темы оформления Google Chrome.

Пример с иконкой я использовал здесь для наглядности, на самом деле всё гораздо проще — у каждого расширения есть /manifest.json, успешную загрузку которого и нужно проверять скриптом.

Proof of Concept, оно же Demo

С помощью заранее собранной базы ID расширений, скрипт методом брутфорса проверяет внутренние ресурсы на возможность загрузки извне.

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

Существует две демонстрации, одна более красивая, другая более правильная:

Chrome Web Store Detector

  • Предсобранная база: топ 10к популярных расширений;
  • код сложно назвать открытым после прохода uglify/closure,
  • хотя всё-же есть сниппет кода для детектирования конкретного расширения;
  • запросы происходят к иконкам — для демо красиво, но негативно сказывается на производительности.

Chrome Addons Enumeration

  • Предсобранная база: топ 1к популярных расширений,
  • но можно вытащить базу из первого примера и приспособить сюда;
  • open source, в том числе имеется парсер Web Store на PHP (github)
  • запросы к manifest.json, по ощущениям даже 1к запросов здесь отрабатываются быстрее.

Ты же сказал — пофиксили ?!

Правда. Игрульке не жить. Как я упомянул в начале статьи, всё это дело исправляется в новой версии манифеста.

Но зачем тогда всё это? Я нарочно не сказал «долго не жить», или «жить не долго». Потому как сменить версию манифеста у всех расширений — это вам не через Google Update патч закатать.

Во первых, стабильный Google Chrome 18 для которого рекомендуется этот манифест, только-только вышел. И мало кто кинется сразу фиксить свои расширения, боясь навредить мифической обратной совместимости и интеграции.

Во вторых простая лень, ведь и так всё работает, какие к чёрту политики?

Сделай сам

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

"manifest_version": 2


Изменение/добавление этой строчки в файле manifest.json переключит Content Security Policy в режим «whitelisting».

Детектирование установленных расширений Google Chrome

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

{
  ...
  "web_accessible_resources": [
    "habra.png"
  ],
  ...
}

На этом закончим

Гордые Огнелисы хоть и сами не без грешка (имелся идентичный баг), но пока-что могут смело попугать демками своих Хроменьких друзей ещё как минимум до лета, а того и больше :)

Автор: abrwalk

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js