Hlavní navigace

CSS exploit a neexistující soukromí na webu

16. 6. 2008
Doba čtení: 8 minut

Sdílet

Jak je to se soukromím na webu? Jsou uživatelé chráněni nebo mají jen falešný pocit bezpečí? Dnešní článek je o chybě, která se dostala do webových specifikací, dodnes v nich setrvává a nejspíš tam zůstane nadobro. Webové prohlížeče, které se jimi řídí, tak vystavují část uživatelova soukromí na veřejnost.

Již v rané éře webu zobrazovaly prohlížeče odkazy, které uživatel navštívil, odlišnou barvou než odkazy nenavštívené. Jednalo se o praktickou věc a uživatelé si na ni rychle zvykli. Přestože toto chování vypadá naprosto nevinně, je příčinou problémů, které mohou vést k narušení soukromí dnešních uživatelů webu.

Pokud si myslíte, že stránka, kterou právě čtete, o vás nemůže nic zjistit, tak se mýlíte. S jistou pravděpodobností by pomocí tzv. CSS exploitu dokázala odhadnout, jaké vyhledávače používáte, které e-shopy navštěvujete (včetně kategorií, které vás zajímají), zda používáte internetové bankovnictví nebo PayPal, jestli nenavštěvujete politicky nekorektní stránky a mnohem víc. Některé zajímavé příklady si za chvíli rozebereme podrobněji.

Pohled do historie aneb jak to celé vzniklo

Webové prohlížeče zavedly barevné odlišení navštívených odkazů. Prohlížeče si proto interně pamatují historii navštívených odkazů několik dní až týdnů nazpět.

(Autor článku toto chování zaznamenal již u prvních verzí prohlížeče Mosaic z roku 1994, ovšem nevylučuje, že se vyskytlo i dříve.)

CSS1

Prohlížeče dovolují uživateli nastavit odlišnou barvu
pro navštívené odkazy. Pomocí kaskádových stylů
mohou autoři stránek nastavit navštíveným odkazům
jakékoliv vlastnosti včetně obrázku na pozadí.

V roce 1996 je vydána specifikace CSS1, která zavádí pseudotřídu :visited. Webdesigneři její pomocí mohou u navštívených odkazů nejen nastavovat odlišnou barvu písma, ale prakticky libovolně je stylovat. Ovšem specifikace zavádí i vlastnost background-image, kterou lze libovolnému prvku stránky nastavit obrázek jako pozadí. Tím specifikace dovoluje vytvořit konstrukci #odkaz:visited {background-image:url(trac­king.gif)}, pomocí které autor webové aplikace snadno zjistí, zda uživatel odkaz v nedávné době navštívil (pokud byl sledovaný odkaz navštíven, je obrázek stažen a tím i vytvořen záznam v logu na serveru).

Na jedné webové stránce lze najednou ověřit více odkazů, postačí k tomu jeden obrázek, kterému se pro každý testovaný odkaz přiřadí jiný parametr, např. tracking.gif?www­.amazon.com. Celá metoda je velmi efektivní, protože dotazy na server proběhnou pouze u navštívených odkazů. Na jedné webové stránce lze tak snadno otestovat velké množství adres (řádově tisíce i více) a získat tak jistý pohled do uživatelova soukromí.

Obdobně může být využita i inverzní pseudotřída :link, která naopak pokrývá odkazy, které uživatel nenavštívil. Tou dobou si problému zřejmě nikdo ani z tvůrců specifikace CSS ani z výrobců prohlížečů pravděpodobně nevšiml.

Koncem roku 2000 je dokončena specifikace DOM2 Style, která zavádí dynamickou práci s kaskádovými styly pomocí klientského skriptování (JavaScriptu). Pro detekci navštíveného odkazu tak už není třeba obrázek (navštíveným odkazům stačí nastavit např. odlišnou barvu písma a následně ji JavaScriptem otestovat) a lze přidat i umělou inteligenci (např. nejdříve otestovat titulní stránky serverů a pouze, pokud jsou navštíveny, testovat detailně i podstránky).

Z roku 2000 pochází také nejstarší veřejné upozornění na celý problém. Jeho autorem je Jesse Ruderman, který do bugzilly vznikajícího prohlížeče Mozilla napsal: Nastavením stylů pro každý jednotlivý odkaz na stránce je možné zjistit, které odkazy ze seznamu uživatel již navštívil. Upozorňoval tím na první problém ve specifikaci CSS1. V roce 2002 se objevil další zápis v bugzille upozorňující i na problém s DOM2 skriptováním. V témže roce se objevilo i oznámení v Bugtraqu. Od té doby se o problém začíná zajímat i širší veřejnost pod označením „vykrádání historie prohlížeče“ a „CSS exploit“.

CSS exploit se od té doby týká všech běžně rozšířených prohlížečů podporujících kaskádové styly a není známo, že by se některý z nich v blízké době chystal přijít s řešením. Jak si ukážeme, najít řešení není jednoduché, pokud je to vůbec možné.

CSS exploit si můžete otestovat ve svém prohlížeči na jedné z mnoha ukázek. Tato verze používá JavaScript, pokud ho máte vypnutý, nebude ukázka fungovat. Ovšem před CSS exploitem obecně vás vypnutý JavaScript neuchrání, zranitelný je každý prohlížeč podporující specifikaci CSS1.

CSS2

Jedna z prvních ukázek CSS exploitu,
jejímž autorem je Henrik Gemal.

Omezení CSS exploitu

CSS exploit zafunguje pouze při plné shodě adresy. Lze tak zjišťovat pouze snadno uhodnutelné adresy nebo adresy z pevného seznamu, např.:

www.example.com/lo­gin
www.example.com/ga­llery?cat=2&pho­to=128
www.example.com/bu­y/books/poetry/?pro­ductid=72

Pokud adresa obsahuje parametry měnící se podle uživatele nebo cesty, kudy na stránku došel (typicky adresy produktů na Amazonu nebo adresy s identifikátorem PHP session), bude adresa prakticky nedetekovatelná. Takové adresy se ovšem nepoužívají často, mj. se s nimi špatně pracuje a ani vyhledávače je nemívají příliš v lásce. Proto velké množství adres na Internetu je CSS exploitem detekovatelných. Zkuste se sami podívat do historie vašeho prohlížeče a odhadnout, kolik z vámi navštívených adres je snadno detekovatelných CSS exploitem.

CSS exploit se týká pouze stránek uložených v historii prohlížeče. Pokud uživatel historii pravidelně maže (některé prohlížeče ji umí před ukončením mazat automaticky), snižuje tím i riziko.

Lesk a bída CSS exploitu

Ačkoliv je problém známý několik let, nikdo nebyl nachytán a obviněn z jeho zneužívání. Buď se CSS exploit často nepoužívá nebo jen velmi opatrně. Jeho veřejné používání může být lákavé a např. nedávno se objevil článek PrivacyPreserving History Mining for Web Browsers popisující možné využívání CSS exploitu i s jistým zachováním uživatelova soukromí. Je vidět, že o informace z uživatelovy historie je zájem a hledá se jen způsob, jak cestu k těmto informacím veřejně posvětit, aby ji mohly bez obav z případných osočení (nebo dokonce žalob) používat i veřejné subjekty.

Na webu najdeme řadu možných scénářů zneužití CSS exploitu. Uvádím ty zajímavé.

Lze zjistit, zda uživatel zadává do vyhledávače vybrané dotazy a tím sledovat jeho potenciální zájmy. Dotazy na vyhledávače jsou součástí adresy, a je tedy možné je detekovat. Některé vyhledávače to komplikují, např. u Googlu se adresa liší pro různé jazykové verze nebo dokonce prohlížeče, ale počet kombinací není nijak nepřekonatelný. Pokud by Evropská Unie skutečně začala trestat lidi hledající ve vyhledávačích slova terorismus nebo bomba, CSS exploit jí přijde jistě vhod.

Pokud aplikace zasílá heslo jako součást adresy, je možné krátká hesla tímto způsobem rozlousknout. Dnes se s heslem v adrese již nesetkáme tak často, ovšem okolo roku 2000, kdy byl problém popsán, se nejednalo o výjimky. Zdůrazňuji, že úplně postačí, aby se v aplikaci během přihlášení vyskytla jedna jediná adresa, která bude heslo obsahovat, a aplikace je náchylná k útoku. Stačí jediný GET formulář zasílající heslo, a to i v případě, že se jedná o HTTPS spojení. Obranou je zasílat hesla jedině v POST datech, posílat je jednorázově zašifrovaná apod.

E-shopy mohou kontrolovat, zda navštěvujete jejich konkurenci (případně i které sekce konkurenčních e-shopů, zda u nich máte účet a jestli jste si tam již něco koupili) a podle toho vám nabídnout adekvátně nižší ceny nebo naopak přidražit. Uvedené neplatí automaticky pro každý e-shop, opět záleží, zda lze snadno detekovat jednotlivé adresy e-shopu, např. u Amazonu je to komplikované, u řady českých e-shopů to není velký problém.

Útočník může odhadnout, jakou banku používáte (zvláštní, že to autoři phishingových útoků dosud nepoužívají). Může detekovat adresu přihlašovací stránky bankovnictví nebo ještě lépe stránku, která se zobrazí po úspěšném přihlášení. Některá bankovnictví do adresy vkládají měnící se parametr a jsou proto hůře detekovatelná.

CSS exploit, byť má svá omezení, tak mohou úspěšně používat státní orgány nebo policie, mohou ho zneužívat již zmíněné phishingové útoky a podnikatelům může sloužit pro zlepšení cílené reklamy.

Jak se CSS exploitu bránit

  • Používat prohlížeč, který není k CSS exploitu náchylný – typicky textové prohlížeče, které nepodporují kaskádové styly.
  • Použít nastavení prohlížeče nebo jeho úpravu, která útoku zabrání. Pro Firefox existuje rozšíření SafeHistory, které vás před CSS exploitem ochrání. Autor článku nenalezl řešení pro žádný další prohlížeč, ale nemůže zcela vyloučit, že takové řešení existuje.
  • Pravidelným mazáním historie (nejlépe po každém ukončení prohlížeče) můžete riziko CSS exploitu alespoň snížit.

Zmíněná řešení jsou ovšem spojena s jistým snížením uživatelského komfortu. Uživatele zvyklé na pohodlí svých aplikací budete k používání textových prohlížečů jen těžko přemlouvat. Podobně mazání historie prohlížeče není vždy žádoucí, např. prohlížeč nebude uživateli nabízet doplňování adres a uživatel si je bude muset pamatovat a psát ručně.

Řešení, které nabízí SafeHistory, je v tomto ohledu nejšetrnější. SafeHistory ponechává historii prohlížeče nedotčenu, ale upravuje zobrazování stránek, aby se všechny odkazy tvářily jako nenavštívené.

(Ne)reakce prohlížečů

Prohlížeče zatím na problém nezareagovaly (připomínám, že o problému vědí minimálně od roku 2000). Na jedné straně se do problému dostaly nevinně, jelikož chyba je součástí samotné specifikace CSS1 a snahy o řešení problému jsou jejím porušením. Na druhou stranu by prohlížeče neměly uživatelské soukromí brát na lehkou váhu.

Někdo může podotknout, že postačí jednoduchá úprava chování prohlížečů, např. zabránit JavaScriptu přistupovat k barvě odkazů a problém je vyřešen. Ovšem tak jednoduché to není.

Pro CSS exploit lze totiž použít prakticky libovolnou vlastnost kaskádových stylů a její detekce se navíc nemusí týkat pouze odkazů, ale i všech potomků odkazu, všech sourozeneckých prvků následujících za odkazem (při použití selektoru „+“ pro sousední sourozence) i všech rodičovských prvků odkazu (např. změna výšky odkazu se může projevit na výšce rodičovského prvku i všech jeho předků konče samotným kořenovým prvkem dokumentu). Ve výsledku se tak stylování může projevit na tolika místech (X)HTML dokumentu, že omezení přístupu k nastylovaným hodnotám není schůdné řešení.

Další cestou by bylo striktně omezit pseudotřídy :link a :visited tak, aby pomocí nich šla nastavovat pouze barva odkazu a barva jeho pozadí (všechny další CSS vlastnosti by se v pravidle ignorovaly) a k těmto vlastnostem zabránit přistupovat z JavaScriptu. To by skutečně mohlo být řešení (byť by bylo v rozporu se specifikací CSS1), není ovšem známo, kolik stávajících webových stránek by touto změnou mohlo být rozbito.

Najít čisté řešení je tedy nemožné, prohlížeče se tak nejspíš nevyhnou cestě spojené se snížením uživatelského komfortu.

UX DAy - tip 2

Vyhlídky do budoucnosti

Je pravděpodobné, že všechny prohlížeče dříve nebo později přijdou s řešením podobným tomu, co nabízí SafeHistory. Je ovšem málo pravděpodobné, že by prohlížeče takové chování nabídly ve svém výchozím nastavení, již vzhledem ke zmíněnému uživatelskému komfortu. Bude se nejspíše jednat jen o volbu pro pokročilejší uživatele.

A tak ačkoliv v souboji bezpečnostních děr dnes jakžtakž vyhrávají prohlížeče (ve světě automatických aktualizací bývají chyby zpravidla záplatovány dříve, než nastane skutečný průšvih), v souboji o soukromí uživatelů tento průšvih trvá již řadu let a nikdo s ním nic nedělá. Pro běžné uživatele, kteří používají výchozí nastavení prohlížečů, soukromí na webu již řadu let de facto vůbec neexistuje a jen tak existovat nebude.

Je váš prohlížeč náchylný k CSS exploitu?

Byl pro vás článek přínosný?

Autor článku

Martin Hassman vymyslel a založil projekt Zdroják. Absolvoval Vysokou školu chemicko-technologickou v Praze. Pracoval jako webový vývojář a specialista na technologie Mozilla.org.