Bezpečnost

    Proč adresy URL prozrazují citlivé údaje (a jak to řešit)

    Historie prohlížeče, serverové logy, CDN i hlavička Referer drží celé URL, i přes HTTPS. Kudy odkazy unikají a jak navrhnout URL, kterým únik neublíží.

    W. Miller · Aktualizováno · O LinkPilotu

    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í:

    1. 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.
    2. E-mailová brána příjemce URL přepíše a zapíše a při kliknutí ji stáhne znovu.
    3. DNS přeloží example.com, takže název hostitele (ne cesta) je teď v logech resolveru.
    4. 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 ..."
    
    1. CDN před serverem zapíše stejnou URL a uchová ji podle vlastních pravidel.
    2. 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.
    3. 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)AnoAnoZáleží na pravidlechAno
    Dotaz (?token=abc123)AnoAnoZáleží na pravidlechAno
    Za znakem # (#abc123)NeNeNeAno

    Čá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 GET vracejte jen metadata a obsah vydejte až po výslovném POST, 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-referrer a <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.

    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í.

    Otevřít nástroj

    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é.

    Zdroje

    Nástroje k tomuto článku

    Časté dotazy

    LinkPilot pošle tajný odkaz, který po otevření zmizí.

    Zašifruje se ve vašem prohlížeči, zobrazí se jednou a pak se zničí. Bez účtu.

    Vytvořit tajný odkaz

    Čtěte dál