Taky vidíte posledních pár dní na stránce Ulož.to čínské znaky? Je to jedna z chyb, která může mít dopady na bezpečnost webu – to se už ale málo ví. O co jde?
Web Ulož.to na tomto místě má reklamu, ale při jejím umístění zanedbal několik zásad, tedy zejména určení znakové sady (např.: UTF-8, v tomto případě Windows-1250).
Chyba je konkrétně v souboru o2-search-bar2.html (archiv), který má reklamu zobrazit. Tato stránka nemá nikde definovanou znakovou sadu a tak se prohlížeč musí rozhodnout sám, jakou zvolí. Chrome na OS X se rozhodl pro UTF-16BE, nicméně protože soubor je ve skutečnosti v jiném kódování, zobrazily se nesmyslné čínské znaky.
A právě tato chyba jde zneužít pro útok. Pokud totiž není sada určena, může se do kódu vpašovat něco, co bude vypadat a fungovat jinak v každém kódování.
Vytvořil jsem ukázkový příklad takové zákeřné stránky: danger-encoding.html. Nebojte se, tahle stránka je pouze ukázka, Vašemu počítači neublíží. Stránka se skládá ze dvou částí, každá je napsána v jiném kódování. Prohlížeč ale v jednom okamžiku dokáže porozumět pouze jednomu a to se použije.
A to může útočník ovlivnit (nejen) díky vlastnosti prohlížečů, které u IFRAME bez vlastní definice kódování nastaví kódování rodiče. Stejný kód načtený do stránek s různým kódováním:
- Zákeřná stránka načtená do IFRAME s kódováním WIN-1250
- Zákeřná stránka načtená do IFRAME s kódováním UTF-16
Největší nebezpečí této chyby spočívá ve snadném obejití ochran, filtrů a escapování – takže útočník může za určitých okolností dostat na váš web obsah, který tam nechcete, stačí jen, aby ho tam dostal v jiném kódování a pak přiměl prohlížeč uživatele, aby jej v takovém kódování načetl.
Všechny léty prověřené escapovací funkce (htmlspecialchars(), mysql_real_escape_string(), ap.) totiž fungují pouze ve znakové sadě, kterou očekávají – nedokáží zneškodnit zákeřný kód, který se schován do jiné znakové sady.
Proto na svém webu pečlivě vyplňujte kódování. A nebo ještě lépe: nastavte si na serveru posílání výchozího kódování, pokud nebude určeno jinak:
- Apache:
AddDefaultCharset utf-8
- Nginx:
charset UTF-8;
Zajistíte tak, že kód bude aplikace na serveru zpracovávat ve stejném kódování jako prohlížeč uživatele a do kódu se tak nemůže schovat nic, co by prošlo běžnými filtry, pokud je používáte správně.
Důležité: Nepokoušejte se tento ověřený postup »inovovat« třeba snahou preventivně escapovat vstup pro všechna známá kódování. Jednak je jich opravdu hodně a na některé určitě zapomenenete, ale především si tím zaručeně data poškodíte.
Zkušenější čtenář správně namítne, že běžné escapovací funkce pro WIN-1250 zlikvidují nebezpečné znaky i v UTF-16 (byť jej zcela rozbijí). Ano, to je pravda, UTF-16 jsem zvolil pouze pro demonstraci. Útočník by si určitě zvolil UTF-7, které je bitově posunuté a jeho úmysl schová lépe.
Původně vydáno jako status na Facebooku.