Adresa URL působí soukromě, protože ji mají mít jen ti, kterým ji pošlete. Ve skutečnosti patří URL k nejčastěji zaznamenávaným údajům na webu: zapisují, kopírují a přeposílají ji systémy, které se vás na svolení nikdy neptaly a které nemůžete zkontrolovat. Tady je přesně popsáno, kudy uniká a jak navrhnout odkazy, kterým únik neublíží. Proto také generátor jednorázových tajných odkazů drží dešifrovací klíč v části odkazu za znakem #: ta se do žádného serverového logu nedostane.
Kudy URL uniká
- Historie prohlížeče. Každá navštívená URL se ukládá lokálně a může se synchronizovat do dalších zařízení i do synchronizační služby výrobce prohlížeče.
- Přístupové logy HTTP serverů. Většina serverů ve výchozím nastavení zapisuje celou cestu požadavku i řetězec dotazu. Kdo má přístup k logům, má i URL.
- Reverzní proxy a CDN. Cloudflare, Fastly, váš load balancer: všechny zapisují URL a každý ji uchovává podle vlastních pravidel.
- Systémy pro sběr logů. Přístupové logy zřídka zůstanou na jednom stroji. Odesílají se do centrálních služeb pro logování a monitoring, takže systémů, které URL drží, přibývá.
- Hlavičky Referer. Když stránka odkazuje na prostředek třetí strany,
prohlížeč může zdrojovou URL poslat v hlavičce
Referer. Dostanou ji analytické skripty, vložená videa i reklamní pixely. - Rozšíření prohlížeče. Rozšíření s oprávněním „číst historii prohlížení“ vidí každou URL, včetně části za znakem #.
- Synchronizace záložek. Uložené záložky se synchronizují mezi zařízeními uživatele i na servery výrobce prohlížeče.
- Nástroje pro náhledy odkazů. Slack, Teams, iMessage, LinkedIn a e-mailoví klienti stahují URL, aby zobrazili náhled. Dělají to potichu ve chvíli, kdy se zpráva odešle.
- Firemní proxy a e-mailové brány. Mnoho organizací kontroluje, přepisuje a zapisuje každou URL, která překročí jejich hranici.
Udrží HTTPS adresu URL v soukromí?
Ne. HTTPS šifruje URL během přenosu a nic jiného; obě strany ji dál ukládají. Vyplatí se to říct přesně, protože „spojení je šifrované“ se často čte jako „URL je soukromá“.
TLS šifruje cestu a řetězec dotazu během přenosu: kdo sleduje síť
mezi prohlížečem a serverem, /reset?token=... nepřečte.
Co TLS neskryje: název cílového hostitele (je vidět při překladu DNS
a u většiny dnešních spojení i v poli TLS SNI) a vše, co se děje na obou
koncích. Prohlížeč celou URL dál zapisuje do historie a server ji
dál zapisuje do přístupového logu. Šifrování při přenosu chrání cestu po síti,
ne oba konce, a právě na koncích URL uniká.
Příklad z praxe: život jedné URL
Sledujme jednu citlivou URL, třeba odkaz pro obnovení hesla
https://example.com/reset?token=8f3a91..., od odeslání po kliknutí:
- Poskytovatel e-mailu ukládá zprávu (i s URL) na neurčito a jeho bezpečnostní skener může URL při doručení stáhnout.
- E-mailová brána příjemce URL přepíše a zapíše a při kliknutí ji stáhne znovu.
- DNS přeloží
example.com, takže název hostitele (ne cesta) je teď v logech resolveru. - Webový server zapíše celý řádek požadavku do přístupového logu. Záznam ve výchozím formátu „combined“ serveru nginx/Apache vypadá takto:
203.0.113.7 - - [14/Jul/2026:09:12:45 +0000]
"GET /reset?token=8f3a91... HTTP/1.1" 200 5123 "-" "Mozilla/5.0 ..."
- CDN před serverem zapíše stejnou URL a uchová ji podle vlastních pravidel.
- Analytický skript stránky zaznamená URL stránky i s celým řetězcem dotazu v systému třetí strany, pokud není výslovně nastaven tak, aby ho odstranil.
- Prohlížeč uloží URL do historie a synchronizuje ji.
Jedno odeslání, sedm kopií, které drží nejméně pět organizací. Nic z toho nepotřebovalo útočníka. Takhle web funguje, když dělá přesně to, k čemu byl navržen.
Hlavička Referer v praxi
Pokud stránka pro zobrazení tajné zprávy odkazuje na jakýkoli externí prostředek (písmo
z CDN, analytický skript, vložený obrázek), prohlížeč může tomuto původu
poslat URL stránky v hlavičce Referer.
Moderní prohlížeče mají ve výchozím nastavení strict-origin-when-cross-origin
(MDN: Referrer-Policy),
které u požadavků na jiný původ zkrátí referrer jen na původ
(https://example.com/ místo celé cesty). To je skutečný
pokrok, ale nelze na něj spoléhat: požadavky na stejný původ
dál nesou celou URL, pravidla na úrovni stránky mohou výchozí nastavení
uvolnit a starší klienti a vložená zobrazení webu (webview) se chovají různě.
Dvě praktická opatření:
<!-- Strip the referer for outbound requests on the page -->
<meta name="referrer" content="no-referrer" />
Referrer-Policy: no-referrer
Hlavička platí pro celý web, meta tag pro konkrétní stránku. Pro vícevrstvou ochranu použijte obojí. Ještě lepší je citlivé stránky servírovat úplně bez prostředků třetích stran, aby nebylo komu referrer poslat.
Je token bezpečnější v cestě, v řetězci dotazu, nebo za znakem #?
Jen část za znakem # zůstává mimo požadavek, a proto jen ona zůstává mimo serverové logy. Cesta a řetězec dotazu jsou na tom stejně. Podle toho, kam token v URL dáte, se mění, kdo ho uvidí:
| Umístění | Posílá se na server? | V serverových logech? | V hlavičce Referer? | V historii prohlížeče? |
|---|---|---|---|---|
Cesta (/s/abc123) | Ano | Ano | Záleží na pravidlech | Ano |
Dotaz (?token=abc123) | Ano | Ano | Záleží na pravidlech | Ano |
Za znakem # (#abc123) | Ne | Ne | Ne | Ano |
Část za znakem # se opravdu liší: podle RFC 3986, oddíl 3.5 se zpracovává na straně klienta a do HTTP požadavku se nikdy nedostane. Proto ji nástroje pro sdílení textu s koncovým šifrováním používají pro dešifrovací klíč: server ho doslova nikdy nedostane. Neviditelná ale není. Přečte ji historie prohlížeče, rozšíření i jakýkoli JavaScript spuštěný na stránce. Rozdíl mezi cestou a řetězcem dotazu naopak na soukromí nic nemění: obojí skončí ve stejných logech.
Problém tokenů pro obnovení hesla
Citlivé tokeny v URL jsou uznávaná třída zranitelností. Přesně tohle popisuje CWE-598 od MITRE („Use of GET Request Method With Sensitive Query Strings“): citlivé údaje v řetězci dotazu skončí v logech, historii a hlavičkách Referer bez ohledu na šifrování přenosu. Proto dobře navržené obnovení hesla nikdy nespoléhá jen na to, že URL zůstane tajná. Token je jednorázový, krátkodobý a vázaný na následnou akci (nastavení nového hesla), takže token, který někdo vytáhne z logu o tři týdny později, je bezcenný.
To je obecné poučení: URL z logů většinou nedostanete, ale můžete zařídit, aby zapsaná URL byla bezcenná dřív, než si ji někdo přečte.
Jak navrhnout URL, kterým únik neublíží
Počítejte s tím, že se každá URL, kterou vytvoříte, nakonec objeví někde, kde nemá, a navrhněte ji tak, aby na tom nezáleželo:
- Jednorázové použití. Po prvním úspěšném přečtení tajnou zprávu zničte, aby uniklá URL byla mrtvá dřív, než se objeví v něčí historii.
- Krátká platnost. Omezte okno, kdy může únik ublížit. URL, která fungovala pět minut, má mnohem menší cenu než URL, která fungovala týden.
- Heslová fráze jiným kanálem. Vyžadujte údaj, který v URL nikdy nebyl. Samotná URL, tedy jediné, co mají logy, pak nestačí.
- Oddělte načtení od zobrazení. Na
GETvracejte jen metadata a obsah vydejte až po výslovnémPOST, aby nástroje pro náhledy odkazů a skenery nemohli tajnou zprávu spotřebovat. - Žádné prostředky třetích stran na citlivých stránkách, k tomu
Referrer-Policy: no-referrera<meta name="robots" content="noindex">. - Ve vlastních logech skryjte cesty k tajným zprávám. V nginx
před zápisem do logu přemapujte URI požadavku (viz dokumentace
ngx_http_log_module
k direktivě
log_format):
map $request_uri $loggable_uri {
~^/s/ "/s/[redacted]";
default $request_uri;
}
log_format redacted '$remote_addr - $remote_user [$time_local] '
'"$request_method $loggable_uri" $status';
access_log /var/log/nginx/access.log redacted;
Máte v rukou jen vlastní logy. Kopie v CDN, proxy a prohlížeči zůstanou, a právě proto nesou hlavní váhu první tři body tohoto seznamu.
Co z toho plyne pro tajné odkazy
Z tohoto modelu hrozeb vychází, jak fungují tajné odkazy v LinkPilotu:
s URL zacházejí tak, že k úniku nevyhnutelně dojde, a samotná URL proto
nikdy nestačí. GET vrací jen metadata; obsah vyžaduje výslovné
zobrazení přes POST, volitelně chráněné heslovou frází, která se
na straně klienta hashuje algoritmem SHA-256. Zničené tajné zprávy, zprávy s vypršelou platností
a zneplatněné zprávy vracejí HTTP 410 a jejich obsah je nevratně přepsán.
Odpovědi se zobrazeným obsahem nesou Cache-Control: no-store a události zobrazení
zapisují místo skutečné IP adresy její hash se solí, která se denně mění.
Jedno otevřeně přiznané omezení uvádí stránka
bezpečnostní architektura: dešifrovací
klíč je v části URL za znakem #, takže za tajnou zprávu je třeba považovat
celý odkaz. A to je přesně riziko, o kterém je tento článek. Krátká
platnost, zničení po přečtení a heslová fráze poslaná jiným kanálem omezují
škody, když odkaz unikne.
Aktualizace z 29. září 2026: tento odstavec původně uváděl, že LinkPilot nenabízí koncové šifrování. Nyní šifruje textový obsah v prohlížeči, včetně příloh.
Vyzkoušejte zdarma, bez registrace
Samozničující zpráva
Pošlete poznámku, která po jednom přečtení zmizí.
Omezení
Návrh URL všechno nevyřeší. Neovlivní, co příjemce udělá po oprávněném přečtení, nesmaže kopie, které už drží třetí strany, a nezachrání URL, která nese osobní údaje na očích. Pokud je v řetězci dotazu e-mailová adresa uživatele, žádná krátká platnost nezařídí, aby se nezapsala do logů. Trvalé pravidlo: nikdy nedávejte do URL údaje, které byste později potřebovali smazat, protože smazat URL ze všech míst, kam se zkopírovala, je prakticky nemožné. Navrhujte místo toho URL, které jsou po úniku bezcenné.
Související články
- Jak fungují jednorázové tajné odkazy
- Skenery odkazů a jednorázové tajné zprávy
- Bezpečné sdílení hesel: srovnání 5 metod
