Upload souborů přes HTTP znamená, že si může uživatel pomocí prohlížeče přímo na stránce vybrat soubor a poslat ho serveru ke zpracování. Soubor je zakódován v hlavičce dotazu, webový server ho dekóduje a předá řídícímu skriptu/programu, který jej zpracuje. Menší nevýhodou je, že prohlížeče mají nastaven příliš krátký timeout při http dotazu. Pokud je soubor veliký (řádově několik megabajtů) tak se díky kódování a díky tomuto timeoutu někdy prohlížeč stránky nedočká. Jak to v praxi probíhá si můžete otestovat zde:
PHP nakládá s příchozími soubory tak, že je uloží do dočasného adresáře (/tmp – dá se konfigurovat) a předá skriptu informace v proměnných, které byly nastaveny v HTML kódu formuláře. Dočasný soubor je automaticky smazán po dokončení skriptu. Pokud chcete soubor permanentně uložit, musíte jej někam zkopírovat (například do BLOBu). Pokud tedy ve formuláři je <INPUT TYPE=FILE NAME=SOUBOR>, pak PHP skript, zpracovávající tento požadavek, obdrží následující proměnné (pokud jste ovšem nezměnili default nastavení register_globals v php.ini):
/* uplna cesta k ulozenemu souboru */ $soubor = '/tmp/AFKSsd4d56'; /* plne jmeno vzdaleneho souboru */ $soubor_name = "C:\Dokumenty\Test.txt"; /* typ dokumentu (MIME) */ $soubor_type = "text/plain"; /* velikost souboru v bajtech */ $soubor_size = 150;
Pokud máte zapnutou volbu track_vars v php.ini (v PHP 4.0.X se nedá vypnout), pak proměnnou $soubor naleznete v poli $HTTP_POST_VARS (manuál tvrdí že jsou tam všechny proměnné, nicméně na mém systému (4.0.2) je tam pouze $soubor, který obsahuje cestu ke vzdálenému souboru). Od verze PHP 4.0.X je všechno přehledně nastaveno v dvourozměrném poli $HTTP_POST_FILES[‚soubor‘] (name, type, size a tmp_name).
Problematiku máme za sebou a nyní k problému. Pokud vytvoříte šikovně pojmenované „INPUTy“ v HTML formuláři, můžete donutit nepřipravený PHP skript, aby pracoval s jiným souborem, jiným způsobem nebo mu změnit informaci o velikosti souboru:
<INPUT TYPE="hidden" NAME="soubor" VALUE="/etc/passwd"> <INPUT TYPE="hidden" NAME="soubor_name" VALUE="c:\bla\bla\fake.txt"> <INPUT TYPE="hidden" NAME="soubor_type" VALUE="text/plain"> <INPUT TYPE="hidden" NAME="soubor_size" VALUE="500000">
Jistě mi dáte za pravdu, že PHP skript bude přinejmenším zmaten. V nejhorším případě provede uložení souboru /etc/passwd do databáze a uživatel si ho pak v klidu stáhne (pokud to webová aplikace umožňuje). Tato chyba se týká pouze skriptů, které jakkoliv nakládají s http file upload.
Nabízí se hned několik řešení. Jednak můžete úplně vypnout file upload, což je nejbezpečnější. Druhým řešením (zejména pro ty, kteří nemají možnost modifikovat php.ini) je kontrolovat, zda proměnná $soubor_* není obsažena v $HTTP_*_VARS polích. Pokud je, ignorujte ji. Pokud máte PHP 4.0.X, jste za vodou. Používejte zbrusu nové globální pole $HTTP_POST_FILES. Jelikož je toto pole vícerozměrné, odpadá možnost mystifikovat skript (tzn. $HTTP_POST_FILES[‚soubor‘][‚tmp_name‘] útočník nezmění). Blíže viz. dokumentace.
Bezpečnostní chyby v PHP jako takovém se vyskytují velmi zřídka. To se ovšem nedá říct o aplikacích, napsaných v PHP. Programů a úloh v PHP je opravdu obrovské množství a díky tomu, že PHP má v sobě funkce, které umožňují operovat se souborovým systémem počítače, otevírat sockety nebo používat různé protokoly, mohou být aplikace, které nainstalujete na svůj systém velmi nebezpečné. Pokud si programátor nedá pozor (nebo člověk, který aplikaci instaluje – stačí nešikovná konfigurace), bude překvapen. Útočník totiž nemusí být žádný hacker-specialista. Stačí, když zná protokol HTTP, PHP a jeho funkce, operační systém na kterém aplikace běží a má nějaké ty zkušenosti. Takový phpFileBrowser by mohl být pro útočníka velmi zajímavým odrazovým můstkem. Aplikace jsou většinou s otevřeným kódem, což útok ještě více usnadňuje. Musíme být pozorní nebo prostě doufat, že bude chyba odhalena a odstraněna včas.
O PHP
PHP je skriptovací interpretovaný jazyk vyvíjený již od roku 1994 (dříve měl název PHP/FI), masově se však rozšířila až třetí řada. V současnosti jsou dostupné (a nejpoužívanější) dvě řady verzí: 3.0.X a 4.0.X. Řadu 3.0.X spravuje open source komunita a její vývoj byl zastaven a nyní můžeme čekat jen minoritní verze opravující chyby. Řadu 4.0.X spravuje firma ZEND, kterou založili hlavní programátoři řady 3.0.X (Andi Gutmans a Zeev Suraski). Tito chlapíci se rozhodli kompletně přeprogramovat jádro, což také udělali a díky tomu je nová řada několikanásobně rychlejší a přislíbili otevřený vývoj nových verzí pod licencí PHP, zcela nový debugger, optimalizátor, kompilátor, cache a kompletní prostředí ve stylu InterDev (zatím je dostupný pouze optimalizátor – Zend Optimizer, avšak tento produkt již není open source). Myslím že firma Zend Technologies toho má v rukávu ještě mnoho a že se teprve rozjíždí.
Reference:
www.securityfocus.com
www.php.net
www.php.cz
www.php.cz/projects.php
www.zend.com
phplib.netuse.de
phpclub.unet.ru
www.phpwizard.net