Nahrávání souborů na server je jednou z nejnebezpečnějších činností, kterou můžete udělat. Hrozí velké množství bezpečnostních rizik, s kterými se budete muset vypořádat. Zvláště zde se vyplatí dodržovat pravidlo – Ke každému přistupujte jako by byl bezpečnostní hrozbou.
Nejčastěji dovolujeme nahrávat našim uživatelům na server nějaký obrázek. Ovšem i tak jednoduchá věc jako je profilová fotka v sobě může skrývat nebezpečný kód. Asi nejhorší chybu, kterou můžete udělat je spoléhat se na prohlížeč a javascript, který zkontroluje příponu souboru. Tento test by zde měl být spíše jako upozornění pro uživatele a kvůli úspoře výkonu. Nahrávání souborů na server přes formulář totiž spolkne jeden PHP proces.
Samotná kontrola souboru by tak měla probíhat na serveru. Spousta programátorů kontroluje mime type místo přípony přípony. Obojí se dá zfalšovat, ale stále je lepší když nahrajete na server soubor neco.jpg s PHP skriptem, než neco.jpg.php, který se dá spustit, pokud útočník zjistí, kam je ukládáte. Nedoporučuje se ani test hlaviček kvůli velikosti obrázku.
Základní obranou je tedy jakkoliv znemožnit komukoliv spustit soubor na serveru. Představte si jej jako spustitelný PHP a vašim úkolem je znemožnit jeho spuštění, tak aby mohl napáchat nějakou škodu. Jistě vás několik možností hned napadlo. Pojďme se podívat na ty nejběžnější.
Takže aby v něm server nespustil jakýkoliv skript, nesmí mít možnost vůbec v něm tento skript vidět. Okamžitě tedy zkontrolovat příponu a vše co není jpg, gif, png či jpeg smazat/zahodit a netrápit se tím. Pokud někdo propašoval přes formulář nepovolenou příponu, tak zřejmě nemá zájem nahrávat obrázky, ale má postranní úmysly.
Zajímavé bezpečnostní opatření je také nastavit u nahraných souborů práva na 0666. Takovýto soubor může být pouze čten a lze do něj zapisovat. Nemůže být ale spuštěn. Což u obrázku není nejmenší problém, protože je chceme pouze servírovat prohlížeči našeho návštěvníka.
Soubory také můžeme umístit do adresáře, ke kterému nebude mít nikdo zvenčí přístup. Teoreticky by je šlo i ukládat do databáze, ale to už je technicky náročnější a i zbytečné. K souborům, které jsou mimo dosah lidí však můžeme přistupovat ze serveru a servírovat jim je přes PHP skript:
<?php // obsah skriptu ukazobrazek.php // ID obrázku, který si vytáhneme je voláno v $_GET["id"] // kód, který nám podle ID zjistí název souboru a otestuje zdali je skutečný, pak jej vloží do $nazevsouboru // vytvoříme hlavičku obrázku Header('Content-Type: image/jpeg'); readfile('zabezpeceneobrazky/'.$nazevsouboru); ?>
Tento skript pak normálně voláme z parametru src:
<img src=“ukazobrazek.php?id=1″>
Je třeba si dát pozor na neviditelné znaky než odešlete hlavičku. Obecně při debugování je lepší mít zobrazování všech chyb 🙂
Samozřejmě existuje velké množství dalších nebezpečí spojených s obrázky, ale většinou jsou servery na sdíleném hostingu proti tomuto dobře bráněny díky profesionální konfiguraci. I to je jeden z důvodů, proč si radši vybrat společnost s nějakým renomé, než fan projekt lidí bez větších zkušeností. Pokud máte VPS je nastavení o dost složitější a ošetřit všechno nemusí být na první pohled tak jednoduché.
V případě uploadování souboru se vyplatí sledovat a zapisovat případné chyby s tím spojené. Návštěvníkům vypisujte obecné informace jako „Nahrávání se nezdařilo, zkuste to později. Pokud se problém bude opakovat, kontaktujte administrátora.“ ale pro vás je lepší co možná nejvíce věcí logovat. Většin programátorů má vlastní zaznamenávání chyb s tím, že jim dorazí email a mohou okamžitě jednat.
Tento článek byl byl přečten 2692 krát