HTML5: nová bezpečnostní rizika

HTML 5

Bezpečnost webů je velmi široké téma, mnohokrát probírané a diskutované. Pojďme se dnes zaměřit především na rizika a hrozby, které přináší nové technologie z rodiny HTML5. S nimi totiž přichází i celá řada nových zranitelných míst, která jsou o to nebezpečnější, že o nich tvůrci webů zatím ještě nevědí.

Vymezení

V tomto článku se nebudeme věnovat útokům proti serverovým technologiím a serverům. Přesto hlavní tíže obrany proti dále popsaným technikám leží právě na serverech, resp. ve správném ošetření HTML kódu, který ze serveru odchází a který na něj (to především) přichází. Nebudeme se věnovat ani klasickým útokům typu Man-in-the-Middle. Bohatě si vystačíme s tím, co nabízí samotný prohlížeč.

Co je možné provést s prohlížečem?

Asi nejznámější typ útoku je XSS, pomocí kterého je do cílové stránky vložen cizí JavaScriptový kód. Buď tak, že jej server nabízí sám, protože si jej natrvalo uložil (persistentní XSS), nebo je vložen do URL jako vyhledávaná fráze a po odeslání ji server zopakuje na stránce výsledků jako „Hledanou frázi ….. se nepodařilo nalézt, omlouváme se“. Pokud jako „hledanou frázi“ server zopakuje doslova to, co dostal, může být vykonán cizí JavaScriptový kód.

„Jak mi může JavaScript ublížit?“

Když jsem se před několika lety bavil s kamarádem po Jabberu, poslal mi odkaz na svou stránku. Napsal jsem mu, že „tam nic nevidím, že mám zakázaný JS, tak ať počká, načtu znovu…“ Kamarád se podivil, proč mám JS na neznámých stránkách sakumprásk zakázaný – sám tvoří stránky mnoho let a JavaScript zná, tak po krátké diskusi položil otázku z mezititulku. „Jasně, vím o XSS, ale co mi může cizí skript na stránce udělat? Může mi tím zavirovat počítač? Nemůže!“ Pak jsme si vysvětlili, co může a nemůže, a kamarád uznal, že riziko je možná větší.

Pro ty, kterým není zřejmé, dodám: Útočnický skript se provede se stejnými oprávněními jako skripty, které na stránku patří. Tedy může změnit HTML stránku. Může nasimulovat třeba přihlašovací formulář. Může dokonce nasimulovat přihlašovací formulář k úplně jiné stránce ve chvíli, když se uživatel nedívá. Může vám sebrat uživatelské přihlašovací údaje. Může využít toho, že uživatelé mívají otevřené sessions např. k e-mailům a změnit je pomocí clickjackingu. Ne, nepoškodí váš počítač; útoky tohoto typu jsou zaměřené proti vaší identitě.

Nebezpečné konstrukce

Tvůrci webů se naučili v předchozích klidných letech některé bezpečnostní postupy – minimálně filtrovat uživatelem vložený text a vyhodit z něj vše, co je podle jejich názoru nebezpečné. Někteří filtrují tag SCRIPT, další zaměňují všechny znaky „<“ a „>“ za entity, jiní vyhodí vše, co je HTML entita, rovnou. Když to jde, proč ne? Ale čtenáři vyžadují prostor ke komentářům, a chtějí svůj názor nejen sdělit, ale i formátovat. Za redakčními systémy sedí redaktoři, bloggeři a další podobní, kterým nelze z textů vyházet veškeré HTML. Vyrojily se proto více či méně důmyslné nástroje, které fungují na principu blacklistu „nebezpečných tagů“ či naopak whitelistu „bezpečných tagů a povolených atributů“. Bohužel mnohdy tyto techniky nabízejí jen falešný pocit bezpečí, což je pravděpodobně ten nejhorší možný stav: sníží ostražitost správce a na problém je zaděláno…

Je to zlé?

Ano. Když jsem před dvěma lety seděl v porotě WebTop100, byla k nonpersistentnímu XSS útoku náchylná zhruba třetina hodnocených webů. Připomínám, že v této soutěži nejsou účastníky blogísky náctiletých slečen, ale weby velkých firem a důvěryhodných institucí. Kompromitace takového webu může být nebezpečná i pro uživatele, co očekávají od podobných stránek důvěryhodnost („Já nevím, jak mi mohli ukrást přihlašovací údaje k mailu, vždyť chodím jen na Seznam a na stránky velkejch firem; žádný porno nebo jiný takový nebezpečný stránky…“)

S minimální mírou nepřesnosti můžeme říct, že nejzásadnější bezpečnostní otázkou v naší vymezené oblasti je, jak zabránit útočníkovi, aby vložil, změnil či spustil skript. Útok může přijít z „divočiny“, ale i zvnitřku (představme si redakční systém, kam redaktoři smí vložit HTML, které se zobrazí na stránkách). Důležité a stále platné pravidlo je nevěřit ničemu, co poslal uživatel.

Technologie z rodiny HTML5 jsou v tomto ohledu velmi nebezpečné. Ne snad že by byly děravé samy o sobě nebo že by jejich implementace v prohlížečích byla vadná. Navrženy jsou poměrně robustně a implementace tam, kde jsou implementovány, bývá bezpečná (či rychle opravená). Hlavní problém s bezpečností HTML5 je ten, že přináší mnoho nových možností, jak skript do stránky vložit a spustit, které ale tvůrci webů zatím moc neznají. Skripty mohou být v SVG, může je vyvolat CSS – pokud může kdokoli cokoli z toho změnit, máte zaděláno na problém, protože staré „obranné mechanismy“, zvyklé na XHTML/HTML4, pravděpodobně při detekci těchto nových možností fatálně selžou.

Tvůrci webů pravděpodobně znají (již poněkud letitý) XSS cheatsheet, v němž jsou popsány základní způsoby útoků proti HTML stránkám – ukazuje, jak všelijak lze zamaskovat tag script, a zmiňuje se i o SQL injection atd. Přes své relativní stáří je stále základním studijním materiálem pro každého tvůrce webů. S HTML5 se ale vyrojilo tolik míst, kde se ani kouzelné slůvko „script“ nemusí objevit, že spolehnout se na staré metody rovná se téměř jistě úspěšnému napadení webu.

HTML5 Security Cheatsheet

Mario Heiderich, který se zabývá bezpečností webových aplikací a publikuje v německých magazínech o PHP, uspořádal se svými spolupracovníky impozantní sbírku možných bezpečnostních rizik, především těch, které přináší HTML5 – HTML5 Security Cheatsheet. Sbírka obsahuje v době psaní tohoto článku 110 možných způsobů, jak (převážně pomocí nových technologií – HTML5, CSS3, vendor-specific vlastností, atd.) vložit do stránky skript a vykonat jej. Naleznete tu převážně méně známé, až raritní způsoby, a my si některé z nich ukážeme i v tomto článku.

http://www.sxc.hu/browse.phtml?f=view&amp;id=352344
mpalmerdesign@comcast.net

 

U každého z těchto způsobů je navíc popsáno, v jakých prohlížečích funguje, a v poznámkovém aparátu jsou odkazy na specifikace, které se jej týkají, a tipy jak zabránit útočníkovi v útoku tímto způsobem.

Pozn.aut.: Považuji HTML5 Security Cheatsheet za naprosto zásadní seznam pro každého tvůrce webů, proto jsem nabídl pomoc s překladem do češtiny – překládám jej postupně, ale doufám, že do konce týdne bude překlad kompletní. Máte-li k němu jakékoli připomínky, neváhejte mě kontaktovat – e-mail naleznete v mém profilu. Stejně tak i pokud máte návrh na další způsob útoku, který v seznamu není uveden. Děkuji za pomoc. 

Pojďme se podívat na některé způsoby vkládání a spouštění skriptů z tohoto seznamu podrobněji. Naleznete u nich vždy v závorce odkaz do Cheatsheetu.

Autofocus

Užitečný atribut, který umožní napsat formulář, v němž bude předvybrané vstupní pole, takže uživatel může rovnou začít psát. Je to zároveň způsob, jak vložit do stránky skript a nepoužít ani klíčové slovo SCRIPT. Základem je konstrukce podobná této (#7):

<input type=text onfocus="alert('xss')" autofocus>

Princip je prostý – vložené textové pole je automaticky vybrané (autofocus), a vedlejším efektem je vyvolání obsluhy události focus. Podobně lze vyvolat událost onblur – pomocí dvou prvků, kde oba mají autofocus (#8). Dokonce lze pomocí autofocus spustit kód, vložený jako obsluha události onscroll (#12).

Video

Jeden z nejpopulárnějších HTML5 tagů skrývá rovněž netušené možnosti vložení JavaScriptu. Například v prohlížeči Opera může atribut poster, který udává cestu k obrázku, obsahovat i URI začínající „javascript:“ (#10). Skript může být vložen jako obsluha události onerror v tagu source (#55) nebo video (#56).

Oklamání jednoduchých HTML filtrů

Je třeba dávat pozor i na to, abychom při filtrování nezapomněli na „historické, nepoužívané apod.“ tagy jako třeba FRAMESET. I ten může obsahovat obsluhu události ( onload), která bude vyvolána – a přitom nepřitahovat pozornost klíčovými slovy src nebo script (#31).

Pokud používáte na uživatelský vstup filtr, který nerozloží zdrojový kód a opět ho nesloží zpět, ale pouze reaguje na určité „podezřelé“ konstrukce, může být snadno „oblafnut“ např. pomocí konstrukce s komentářem (#37) nebo konstrukcí, v níž se záškodnický kód tváří jako regulérní součást atributu (#31):

<style><img src="</style><img src=x onerror=alert(1)//">

Prohlížeč této konstrukci porozumí zcela jinak než obyčejný HTML filtr – zatímco filtr bude nejspíš závadnou část považovat za legitimní součást atributu src v prvním tagu IMG, parser uvidí nesmyslné znaky v elementu style a IMG s obsluhou onerror.

Filtr lze oklamat mnoha způsoby. Třeba i špatným zápisem značek (#57).

Neobvyklé události, neobvyklé znaky…

Script vložený do obsluhy událostí onfocus, onblur, onscroll jsme si už ukázali. V IE lze využít třeba i události filterchange (#70).

Prohlížeče Safari a Chrome (verze 5 a 6) zase ignorují některé speciální znaky v URI (#101), což může útočník využít k zamaskování „podezřelého“ řetězce „javascript:“ – co třeba <a href=&#1ja&#2&#3va&#4&#5sc&#6r&#7i&#8p&#11t&#12:alert(1)>XXX</a>? Na takovém URL shoří běžný filtr, založený na kontrole řetězců, jako papírový čert.

V prohlížečích s jádrem Gecko lze zase využít ke spuštění kódu předefinování setterů (#6). Předefinování getterů/setterů je vůbec hezká technika, použitelná k vyvolání skriptu bez zásahu uživatele – například lze předefinovat getter u objektu ReferenceError (či podobného) a pak takovou chybu vyvolat (a ani k tomu nepotřebujete Firefox, protože technika funguje ve všech prohlížečích) (#20). Firefox vám zato nabídne i další možnost – přepsání proprietární metody __noSuchMethod__ objektu Object (#21) a vyvoláním obsluhy této chyby.

Firefox rovněž obsahuje objekt crypto. Tento objekt má metodu, která vykoná na pozadí eval()  – takže filtr, který hledá znaky „eval“, neobjeví, co by objevit měl: <script>crypto.generateCRMFRequest('CN=0',0,0,null,'alert(1)',384,null,'rsa-dual-use')</script> (#5).

Pravé eldorádo pro skrytí útoku představují neobvyklé znakové sady. Například taková UTF-7 (#2):

<meta charset="x-imap4-modified-utf7">&ADz&AGn&AG0&AEf&ACA&AHM&AHI&AGO&AD0&AGn&ACA&AG8Abg&AGUAcgByAG8AcgA9AGEAbABlAHIAdAAoADEAKQ&ACAAPABi

X(HT)ML

Firefox nabízí techniku zvanou E4X, která umožňuje zapisovat JavaScript do XML. Pokud používáte XHTML a vaše stránka je validní XML (a to je, že…), bude ve Firefoxu fungovat takováto podivná konstrukce (#25): <script src="#">{alert(1)}</script>;1. Co se stane? Atribut src říká prohlížeči, že jako zdrojový skript má být použita stránka sama. Pokud je validní X(HT)ML, bude použita a vykonána. E4X vůbec umožňuje zajímavé kousky – (#26), (#58), (#75).

Opera nezůstává pozadu. Víte, že v Opeře lze jako hodnotu XML atributu stylesheet zadat javascript URI (#17)?

Ve všech prohlížečích pak lze podsunout JavaScript například v deklaraci ATTLIST (#67) – a to samosebou nejsou všechny možné způsoby.

CSS

Opera nabízí vendor specific atribut -o-link, kterým můžeme přiřadit elementům odkaz. Jeho zneužití je snadné (#9): <div style="-o-link:'javascript:alert(1)';-o-link-source:current"> vytvoří klikací element z čehokoli, i bez href a src a onclick… Pokud se někdo dostane k CSS, lze to ještě snadněji, i se zamaskováním:

p[foo=bar{}*{-o-link:'javascript:alert(1)'}{}*{-o-link-source:current}]{color:red};

V Exploreru lze zase vhodně manipulovat s obsahem atributu href v tagu LINK (#29) a v direktivě @import (#30) – podstrčením data URI opět dosáhne útočník svého.

SVG

SVG je mocný nástroj pro vektorové ilustrace a animace – a navíc bohatá studnice možných útoků, protože může obsahovat aktivní skripty. Mnohé prohlížeče umožňují odkázat na SVG tam, kde bylo dosud možné vkládat pouze obrázek – ale dovolit to znamená koledovat si, protože SVG nejsou tak „bezpečné“, jako jsou obrázky. Pokud dovolíte ve svých stylech či uživatelsky zadaném HTML odkaz na cizí SVG, můžete mít problém (#11):

<svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>

V podstatě vše, co víte o bezpečnosti v HTML, platí v bledě modrém pro SVG – SVG může obsahovat HTML kód, skripty, obsluhu událostí… V seznamu naleznete řadu útoků založených na SVG.

DoS

Zajímavé jsou útoky, které znemožní práci se stránkou. V Opeře lze použít repeat templates (#13) nebo „vhodně“ napsaný regulární výraz pro kontrolu dat (#14) a zaseknout tak prohlížeč.

V prohlížečích s podporou HTML5 lze udělat formulář nepoužitelným touto hezkou konstrukcí:

<input onblur=focus() autofocus>

A další…

Existují i další možnosti, kudy může útočník vložit nebezpečný kód (a nemusí jít jen o nějaké proprietární vymoženosti typu behavior). Účelem článku rozhodně nebylo čtenáře vyděsit nebo přesvědčit, že „tyhlety internety a HTML5 jsou samé nebezpečí“. Cílem bylo hlavně upozornit na málo známé způsoby a povzbudit tvůrce, aby se o nové technologie zajímali – když ne aktivně, tak alespoň z hlediska bezpečnosti. Nejnebezpečnější je totiž ta technika, kterou moc lidí nezná a skoro nikdo ji nepoužívá.

Závěr

Ukázali jsme si jen jednu oblast webové bezpečnosti – totiž možná místa, kudy může být proveden XSS útok. Je na místě zdůraznit, že jde jen o jednu část celé problematiky, že jsme nepokryli, a ani nemohli pokrýt, bezpečnost celou. Zaměřili jsme se především na méně známé techniky a na ty, které přišly s technologiemi z rodiny HTML5.

Z výše napsaného lze vyčíst několik obecných rad pro autory webů – a to jak pro ty, co píší HTML a client-side, tak i pro ty, co se zabývají serverovou stranou (pro ty především).

Námitka, která vás možná napadla, zní: „To je hrůza… Ještě že nepoužíváme HTML5! A když to tak vidím, tak to radši ani nikdy používat nebudeme!“ Pro vás máme špatnou zprávu: Co na tom, že VY nepoužíváte HTML5 – umí ho prohlížeč vašich návštěvníků! Pokud HTML5 ignorujete a doufáte, že použitím HTML4/XHTML se všem výše zmíněným rizikům vyhnete (a nemusíte je tedy kontrolovat a zabývat se jimi), žijete v bludu.

Tvrdit, že „HTML5 je nebezpečná technologie, protože je samá díra“ je ale stejně krátkozraké. Není o nic „děravější“ než existující technologie. Jen přináší nové možnosti – a každá nová možnost může být zneužita! Nejjistější ochranou proti takovému zneužití je vědět o možných rizicích, a nejnebezpečnějším možným postojem, který k nim lze zaujmout, je ignorance: „HTML5 je nebezpečné, špatné, samá díra, nic nového mi nedá a nikdo ho nepodporuje, proto se jím nebudu zabývat a nemusí mě zajímat!

Vyhněte se různým blacklistům a filtrům, stejně vás neochrání! Možností, jak vložit do stránky skript, je nepřeberně a žádný blacklist je nepokryje. Pokud vaše aplikace přijímá HTML vstup od uživatele a zobrazuje jej, kontrolujte jej podrobně až paranoidně. Rozparsujte vstup stejně jako HTML parser, ponechte pouze povolené tagy, pouze povolené atributy, a v nich si ještě zkontrolujte, zda obsahují jen to, co povolíte (obzvlášť data URI nebo javascript: jsou nebezpečné).

Nepovolte, aby uživatel mohl vložit HTML kód s definovanou obsluhou událostí. Prostě – ne!

Naučte se i to, co je podle vás „nesmysl“, „zbytečnost“ a „prasečina“! Můžete mít k HTML5 velmi rozumné výhrady, ale když ho nebudete používat a znát, tak to ještě neznamená, že zmizí ze světa. Nezapomeňte – to, že nějaký způsob neznáte, neznamená, že neexistuje! 

Slečna u počítače

I pro uživatele lze nalézt ponaučení:

Nemyslete si, že existuje prohlížeč, který je „bezpečný“ (nebo naopak „nebezpečný“)! Říkat „nemám IE, tak se nemusím bát“ (a navíc tomu věřit) je spolehlivá cesta do pekel.

Nevěřte tomu, že stačí „vyhýbat se podezřelým stránkám, být opatrný a chodit jen na ty prověřené“. Nestačí. Kompromitace „důvěryhodné“ stránky je možná, navíc takovým způsobem, že si kompromitace nevšimne prohlížeč, administrátor webu, antivir, antiscam, …

Zakázat JavaScript a povolit jej jen na některých stránkách je poměrně rozumný přístup; bohužel naráží na přesvědčení mnohých tvůrců, že „JavaScript mají všichni“ a „jestli ho někdo nemá, tak ať použije pořádný prohlížeč“. Svou lenost či neschopnost nabídnout alternativní metody přístupu ke stránce pro uživatele se zakázaným JavaScriptem vysvětlují „dobrými důvody“ a poukazem na minoritu lidí se zakázaným JS (a mýlí se). Samosebou, zakázáním JS přijdete o mnohé pokročilé funkce, ale s tím je nutno počítat. Nikdo po tvůrcích nechce, aby vymýšleli třeba WYSIWYG editor v prohlížeči, co by fungoval bez JS – ale požadavek, aby navigace a odkazy na stránky byly dostupné i bez JavaScriptu, je rozumný a jeho nesplnění je na pomezí arogance a pitomosti.

A pamatujte: Neexistuje bezpečný systém, jsou jen systémy, které nebyly zatím úspěšně napadeny. 

Autor děkuje Mariu Heiderichovi za laskavý souhlas s použitím informací z HTML5 Security Cheatsheet a za ochotnou spolupráci.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 17

Přehled komentářů

Jirka V. Moc pěkný
vetesnik Super
pb autofocus?!?
Martin Malý Re: autofocus?!?
Ifo Re: autofocus?!?
Daniel Steigerwald Pochvala + 'javascript:' je prostý label
Jiří Kosek Re: Pochvala + 'javascript:' je prostý label
keff The Spanner a Hackvertor
juraj odveci
Martin Malý Re: odveci
juraj Re: odveci
jurasn Filtr jako PHP knihovna
Mastodont Re: Filtr jako PHP knihovna
Vojta A co JS na tom originálním článku? :-)
Ifo Pěkné.
Martin super článek v jednou vadou
imploder Prostě escapovat
Zdroj: https://www.zdrojak.cz/?p=3362