10
Fotogalerie

Konec User-Agentu. Kvůli „sádlu“ už nikdo spolehlivě nezjistí, co máte za prohlížeč

  • S HTTP hlavičkou User-Agent je spojený celý World Wide Web
  • Google ji ale v Chromu nahradí novou technologií
  • Už kvůli tomu skončil třeba i analytický NetMarketShare

Když jsme před třemi dekádami vynalezli World Wide Web a jeho stránky psané v jazyku HTML přenášené pomocí textového protokolu HTTP, zprvu jsme si vystačili s jedním jediným programem, který to všechno dokázal zobrazit.

Netrvalo to ale dlouho a záhy se prázdné místo díky snaživým vývojářům zaplnilo nepřeberným množstvím nových uživatelských agentů, kterým dnes říkáme webové prohlížeče.

Ahoj, já jsem prohlížeč XYZ

Jelikož je každý takový program trošku jiný, autoři protokolu HTTP brzy přispěchali s novou popisnou hlavičkou User-Agent, pomocí které se prohlížeč v úvodu vzájemné komunikace stručně představil webovému serveru.

Když nahlédneme do surové specifikace protokolu HTTP/1.1 a jeho sekce 5.5.3, dozvíme se, že má hlavička User-Agent vypadat zhruba takto:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Program v tomto případě webovému serveru říká:

Ahoj, jsem program CERN-LineMode (druhý nejstarší WWW prohlížeč na světě) ve verzi 2.15 a k vykreslení jazyka HTML používám jádro Libwww ve verzi 2.17b3.

K čemu byl takový podpis vlastně dobrý? Představme si paralelní vesmír, ve kterém by bylo tehdy obecně známo, že sice jádro Libwww podporuje obrázky ve formátu JPEG, ale kvůli chybě je ve verzi 2.17b3 zpracovává celou věčnost. GIFy naopak vykreslí během okamžiku.

Webový vývojář o tom věděl, a tak mohl jeho server všem uživatelským agentům se stejným podpisem poslal raději obrázky v bezpečnějším formátu GIF.

A když nemáte kečup, dejte tam třeba hořčici

Celé to má ale jeden háček. Specifikace HTTP je v případě hlavičky User-Agent poměrně vágní, a tak si tam může dát každý prohlížeč v podstatě cokoliv, co se mu zamane. Teprve postupem času se vytvořil jakýsi neformální úzus, který však není sám o sobě nijak standardizovaný.

Textový řádek proto začal v průběhu let postupně bobtnat a bobtnat a dnes vypadá v případě Chromu na mém pracovním laptopu asi takto:

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36

A v Edgi na Windows pro změnu takto:

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67

Podpis svého vlastního prohlížeče si můžete zobrazit na této stránce analytické služby StatCounter.

Proč mi tam straší nějaká Mozilla?

Proboha, proč mám v podpisu Mozillu ve verzi 5.0? A co ten Apple Webkit 537.36? O KHTML like Gecko raději ani nemluvě...

Tento neuvěřitelný a v podstatě lživý podpis prohlížeče je daň za zbrklý vývoj a chování vývojářů. Ti totiž v průběhu let začali používat detekci prohlížeče jako filtr pro HTML obsah v takové míře, až musely prohlížeče z důvodu zpětné kompatibility nebo konkurenčního boje začít vědomě lhát. A z tohoto lhaní se stala široce přijímaná norma.

Dejme tomu, že se autor aplikace X rozhodl, že ta poběží jen v prohlížeči Chrome. V těch ostatních s odlišným podpisem User-Agent se pak proto zobrazila jen hláška: „Omlouváme se, ale naše skvělá stránka potřebuje Chrome,“ byť by vše fungovalo třeba i v Opeře.

Aby tedy aplikace X pracovala i ve zmíněné Opeře, její vývojáři do podpisu prohlížeče přidali klíčový výraz „Chrome,“ čímž z něj alespoň na oko udělali prohlížeč od Googlu, když jej tedy autoři stránek tak vyžadují.

No, a pak k tomu přidejte jen čas, dvě dekády soubojů o post tržní jedničky v rámci prohlížečových válek a výsledkem je ten neuvěřitelný guláš, kdy podpis vlastně není podpis, ale spíše výkřik:

Ahoj, já jsem prohlížeč Rudolf a je mi 28 let. Ale jsem i trošku Monika, čerstvá osmnáctka. A vlastně jsem i Bohouš, 29 let. No, ale občas jsem i patnáctiletá Evička, co má ráda roztomilé psíčky s růžovou mašlí.

Čím více Rudolfů, tím kvalitnější fingerprint

Možná jste už vytušili jeden nepříjemný vedlejší efekt. Taková hlavička User-Agent plná Rudolfů, Monik, Bohoušů a Eviček s psíčky se totiž může počítač od počítače výrazně lišit, no a když k tomu přidáte další HTTP hlavičky, ve kterých prohlížeč druhé straně sděluje, co všechno umí, nabízí a podporuje, mohli bychom z toho všeho získat unikátní identifikátor vašeho PC – tedy i vás.

d2d655c3-15a1-4f3b-a35b-91701884f59f
Am I unique? Ano, jsem, i bez trackovací cookie

Této technice říkáme fingerprinting a vyzkoušet si to můžete na vlastní oči třeba na webu AmIUnique. Stránka vytáhne z prohlížeče všechny dílčí dostupné informace a spočítá, jak moc jste pro ni unikátní. V ideálním případě byste měli být jen jeden z mnoha naprosto anonymních–zaměnitelných návštěvníků World Wide Webu, v praxi vám ale stránka sdělí spíše to, že:

Yes! You are unique among the 4 042 827 fingerprints in our entire dataset.

A to je špatně. Pokud jste unikátní pro tuto stránku, můžete být unikátní i pro nějaký sledovací systém na World Wide Webu. Nutno podotknout, že ve světě (nejen) Facebooku a jeho widgetů napříč weby je ale představa naprosté anonymity beztak jen iluzí.

Ahoj prohlížeči, umíš kreslit kočky?

Samotný User-Agent je už do jisté míry roky přežitá technologie. Neměl by už dnes být k ničemu potřebný – tedy pokud vás právě nerozmrazili z kostky ledu včetně počítače s Windows XP a Internet Explorerem 6.

Dnešní webové aplikace se totiž vůbec nemají ptát na to, co máte za prohlížeč a podle toho se chovat, ale mají se ptát na to, jestli váš prohlížeč podporuje konkrétní technologii, kterou zrovna potřebují:

Aplikace: „Nazdar prohlížeči, já jsem narychlo zbastlená javascriptová aplikace, která animuje 3D kočky. Prosím tě, podporuješ technologii WebGL?“

Prohlížeč: „Jasně kámo, WebGL umím levou zadní a ke všemu běžím na PC s rychlou hardwarovou akcelerací!“

Aplikace: „To je boží, tak já jdu animovat!“

334f0983-cd81-40b8-ac1e-c78fa3fcecfc
3D kočka zírající na myš ve WebGL

Ahoj prohlížeči, doufám že nejsi Opera!

Pokud by se ale chod aplikace odvíjel podle detekce prohlížeče skrze hlavičku User-Agent, pak by mohl dialog v našem elegantním pseudokódu vypadat naopak takto:

Aplikace: „Nazdar, nejsi náhodou Opera?“

Prohlížeč: „Jasně, já jsem Opera! Ale také jsem trošku Mozilla. A vlastně i trošku Gecko… No, a jen tak mezi námi, také jsem to a tamto…“

Aplikace: „Aha, takže jsi Opera ☹. Tak to mi polib ešus! Tady máš HTML kód s omluvou, že v Opeře žádné kočky prostě nebudou!“

a1caa57e-76cc-4378-b75b-47f8128842ad
Ne, ne a ještě jednou ne

Aby mě vývojáři neutloukli webovými sušenkami, je nutno podotknout, že se samozřejmě dopouštím určitého zjednodušení a popisuji dokonalý stav věcí.

Technologie je ale stále ve vývoji, takže ani detekce podpory nějaké konkrétní funkce nebyla vždy tak přímočará a elegantní jako v našem příkladu s kočkami. Mnohdy tak byl únik k postupu: „Raději nebudeme podporovat prohlížeč XYZ, jinak se z těch hacků potentujeme,“ lidsky vlastně docela pochopitelný. 

User-Agenta nahradí něco skromnějšího

Co s tím? Jednu z cest se snaží už nějaký rok protlačit Google, který skrze své bazální Chromium ovládá současný World Wide Web – ať už se nám to líbí, či nikoliv.

Ta cesta se jmenuje User-Agent Client Hints a výhledově má zcela nahradit hlavičku User-Agent. Jedná se vlastně o soubor dílčích a mnohem stručnějších HTTP hlaviček uvozených znaky sec-ch-ua a také nové obslužné API pro Javascript.

d17c8153-f989-445c-9e84-1df2851074dc
Takto vypadá seznam HTTP hlaviček, které posílá můj Chrome na Windows 11 při požadavku na stránku zive.cz. Fialově je označená současná hlavička User-Agent a zeleně pak základní hlavičky User-Agent Client Hints. Ty pokročilejší pošle klient až na explicitní vyžádání.

UA Client Hints by dnes měly alespoň v nějaké míře podporovat všechny prohlížeče založené na Chromiu, takže pokud právě teď čtete můj článek v Chromu, Edgi nebo třeba Opeře, níže v boxu by se měly zobrazit údaje o vašem prohlížeči a operačním systému bez dalšího archaického balastu.

Test technologie User Agent Client Hints

Pokud se níže nic nezobrazí, váš webový prohlížeč UA-CH zatím nepodporuje.

Pokud nás naopak právě teď čtete ve Firefoxu nebo jiném prohlížeči, v případě Chromium-based klientů byste viděli zhruba toto:

ab779057-6dd9-44f1-a001-f464e666f68eceb17724-82e2-4034-9262-a6f77f7c1fff
Javascript v bloku výše by měl v desktopovém Chromu a Edgi vypsat podobný výstup 

Kutilové mezi vámi si mohou vše prohlédnout a vyzkoušet na webu JSFiddle a lenoši, kteří neradi klikají na hypertextové odkazy, se mohou podívat rovnou na celý kód, který se spouští v článku, i níže:

<div id="kontejner" style="text-align:left !important"></div>

<script>

// Asynchronní funkce pro zjištění údajů UA Client Hints
async function zjistiPodrobnosti(){
  // Objekt se základními UA informacemi
  const uad = navigator.userAgentData;
  // Ze záákladních dat vytáhneme značky/brands, což by měly být názvy a verze prohližeče
  const znacky = uad.brands;
  // V základním dotazu bychom měli zjistit také to, jestli se jedná o mobilní zařízení
  const mobil = uad.mobile; 
  
  // Pokročilejší UA informace získáme leda asynchronně explicitním dotazem,
  // který je tím pádem připravený i na to, že jej prohlížeč odmítne zodpovědět,
  // pokud to neumožní třeba bezpečnostní politika, náš souhlas apod.
  const hev = await uad.getHighEntropyValues(["platform", "platformVersion", "architecture", "uaFullVersion"]);
  const platforma = hev.platform;            
  const verzePlatformy = hev.platformVersion;
  const architektura = hev.architecture;                  
  const plnaVerze = hev.uaFullVersion;
  
  // Získané údaje vypíšeme do DIV kontejneru s tímto ID
  let kontejner = document.querySelector("#kontejner");
  
  let txt = "<p>";
  txt += "<b>Platforma: </b>" + platforma + "&nbsp;" +  verzePlatformy + "<br />";
  txt += "<b>Architektura: </b>" + architektura + "<br />";
  txt += "<b>Mobilní zařízení: </b>" + mobil + "<br />";
  txt += "<b>Plná verze prohlížeče: </b>" + plnaVerze + "<br />";
  
  // Značka/brand prohlížeče je pole, které může obsahovat vice údajů
  // Kvůli politice tzv. greasingu nicméně i naprosté nesmysly
  txt += "</p><h3>Prohlížeč o sobě říká, že je:</h3>";
  txt += "<p><ul>";
  for(const znacka of znacky){
	  txt += "<li>" + znacka.brand + "&nbsp;" + znacka.version + "</li>";  
  }
  txt += "</ul></p>";

  kontejner.innerHTML = txt;
}

// Konečně zavoláme funkci, která se postupně pokusí zjistit popisné informace
zjistiPodrobnosti();
</script>

Když se podíváte na vlastní výpis nebo obrázek výše, všimnete si, že lze pomocí User-Agent Client Hints z prohlížeče vytáhnout jen několik základních popisných údajů a seznam „Prohlížeč o sobě říká“ je ke všemu docela matoucí.

Jelikož surfuji v Chromu, UA-CH mi prozradí, že mám Google Chrome 92 – potažmo Chromium 92 (licenčně svobodný základ i dalších příbuzných prohlížečů), jenže pak tam straší i jakési Not A;Brand 99. Co to proboha je?

Not A;Brand 99, čili grease – omastek

Kupodivu to není chyba. Je to záměr a říká se mu grease. Je to v podstatě náhodný šum – pomáda/omastek/mazivo/sádlo/tuk, který se může průběžně měnit a slouží k tomu, aby opět nedocházelo k selektivnímu přístupu k prohlížečům. Jednoduše řečeno, pokud se bude ve výčtu značek prohlížečů zobrazovat i nějaký naprostý nesmysl, bude to mást úplně všechny, kteří by nás chtěli fingerprintovat nebo jakkoliv selektovat.

Google v dokumentaci ostatně nabízí i možnost, že ve výčtu občas nezmíní ani sám sebe, čili vývojář už od začátku nesmí počítat s tím, že se pokaždé dozví, s kým přesně má tu čest.

da0b80f5-188c-4ca5-805d-c565a577d3b4
Vědomě vložené nesmysly pro zmatení nepřítele

Některé detailnější údaje (třeba exaktní verze/sestavení prohlížeče) se pak webový server skrze HTTP hlavičky a lokální aplikace skrze Javascript dozví až na druhou asynchronní žádost (viz kód výše), čili je zde technologický prostor třeba k tomu, aby tuto žádost ručně odsouhlasil sám uživatel, anebo ji prohlížeč odmítl na základě stanovené bezpečnostní politiky uživatele, správce IT ve firmě atp.

User-Agent to má spočítané

Prohlížeče založené na Chromiu právě teď používají oba přístupy vedle sebe. Když tedy navštívíte naše stránky, webovému serveru od prohlížeče dorazí jak stará dobrá hlavička User-Agent, tak i nové hlavičky technologie UA-CH.

250e0b86-f7dc-4602-b7d0-ee5ebbd7ee44
Konec klíčové hlavičky byl už několikrát odložen, ale vize je jasná

To se ale časem změní, byť je Google zatím opatrný a čeká, až se používání UA-CH více rozšíří a na společnou loď naskočí i konkurence. Třeba zmíněný Firefox. Karty jsou ale rozdané, User-Agent je ve vývojářské hantýrce deprecated – odepsaný a nové webové aplikace by už s ním raději neměly počítat.

Problém pro analytické služby

No, a to se pomalu dostáváme k nepříjemným konsekvencím. Bohaté údaje z nestandardně-standardní HTTP hlavičky User-Agent totiž už celá desetiletí vycucávají také analytické služby, které je používají k tvorbě statistik webových prohlížečů a operačních systémů mezi internetovými surfaři.

Technologická náhrada User-Agent Client Hints sice může původní hlavičku částečně zastoupit, ale kvůli uměle vkládanému šumu (již zmíněný greasing), zvýšené bezpečnosti i skromnějšímu výčtu údajů na to nemůže být spolehnutí.

Technologie už pohřbila NetMarketShare

Je to skutečně velký problém, a to dokonce i pro ty největší ryby v oboru – třeba službu NetMarketShare, která čtrnáct let měřila právě na základě analýzy hlavičky User-Agent a dalších údajů tržní podíly operačních systémů a webových prohlížečů.

49ef0556-c3f7-4abf-ae04-c7820ebc09f3
NetMarketShare byl jedním ze zlatých standardů veřejné webové analytiky, výstupy pro široký lid ale zastavil už loni v říjnu právě v souvislosti s plánovaným koncem User-Agent 

NetMarketShare už loni sám odhadl, že kvůli těmto pro-anonymizačním technikám bude měření internetu opět o něco komplikovanější a už současné chybové výstupy budou ještě statisticky děravější, a tak na podzim ukončil další měření.

Technologická změna proto občas zlomí vaz i legendám v oboru, faktem ale zůstává, že by měl být surfař zase o kousek ve větším bezpečí před zvědavými zraky ostatních a dalšími strašáky na internetu.

Určitě si přečtěte

Články odjinud