Jun 29 2009
Nastavení PHP pro větší bezpečnost
O tom, jak zvýšit bezpečnost PHP aplikací již bylo napsáno moc a moc. Prvním a základním pravidel je filtrování vstupů uživatelů, na toto téma již bylo popsáno nepřeberné množství přístupů a naprogramováno spousty knihoven, které dělají téměř vše za vás. Druhým, neméně důležitým aspektem je konfigurace PHP direktiv, ať již v přímo v php.ini
nebo pomocí ini_set(...)
či v htaccessu. To, na jaké direktivy by jste se měli zaměřit především, se pokouší odpovědět i PHP Security Consortium ve svém projektu PhpSecInfo.
PhpSecInfo
PhpSecInfo se zaměřuje na řadu klíčových direktiv, které jsou z hlediska bezpečné konfigurace PHP důležité, doporučuje jejich nastavení, popisuje důvody proč je nastavit tak a tak a poskytuje vám přehlednou aplikaci v PHP na to, aby jste si sami mohly vyzkoušet nastavení vašeho serveru či virtualhostu.
Pojďme se blíže na jednotlivé testy a k nim odpovídající direktivy podívat (seznam testů je řazen abecedně, nikoliv podle důležitosti):
- allow_url_fopen
- defaultně on, doporučená hodnota off
- v případě že je povoleno, může skript používat funkcefile_get_contents()
,include()
,require()
, … na vzdálené soubory, což může způsobit vložení závadného kódu z cizího serveru pokud správně neošetříte vstupy
- více o allow_url_fopen direktivě/testu - allow_url_include
- defaultně 0, doporučená hodnota 0
- podobný problém jako allow_url_fopen
- více o allow_url_include direktivě/testu - display_errors
- defaultně on, doporučená hodnota na produkčním serveru off
- vhodné mít zapnuté při ladění a vývoji, na produkčním serveru se doporučuje vypnout
- více o display_errors direktivě/testu - expose_php
- defaultně on, doporučená hodnota off
- rozhodně vypnout vždy, umožňuje potenciálnímu útočníkovi zjistit relativně přesně verzi PHP na serveru a na základě toho využít potencionální bezpečnostní chyby
- více o expose_php direktivě/testu - file_support
- v tomto případě se nejedná o konfigurační direktivu ale pouze název testu, který ověřuje zda vaše verze PHP obsahuje opravu problému zranitelnosti v knihovně cURL
- více o file_support testu - file_uploads
- defaultně on, v případě že ve vaší aplikaci nahrávání souborů nepoužíváte, doporučuje se nastavit off
- více o file_uploads direktivě/testu - force_redirect
- defaultně on, doporučená hodnota on
- direktiva, která se používá pouze v případě že spouštíte PHP přes CGI, na některých web serverech vypnutá (IIS)
- více o force_redirect direktivě/testu - group_id
- nejedná se o direktivu PHP ale proměnou skriptu, tato proměnná definuje ID skupiny systému pod kterým je PHP skript spuštěn a tento test upozorňuje na možné riziko spuštění skriptu privilegovaným/systémovým uživatelem
- více o group_id testu - magic_quotes_gpc
- defaultně on, doporučená hodnota off
- velice známá a v minulosti často diskutovaná direktiva – je-li direktiva zapnuta, pak budou všechny vstupní proměnné _GET, _POST, _COOKIE (a možná i některé další) escapovány pomocíaddslashes
- direktiva magic_quotes_gpc byla přídána především pro zabránění SQL injection, nicméně později se ukázalo, že funkceaddslashes
není zcela dostačující pro některé speciální případy a proto se musí používat speciální escapovací funkce v závislosti na použité databázi, spoléhat tedy na „auto-escapování“ není dobré a proto se doporučuje direktivu nezapínat
- více o magic_quotes_gpc direktivě/testu - memory_limit
- maximální povolená hodnota paměti, kterou může PHP skript alokovat – doporučenou hodnotu těžko definovat, obecně čím méně tím lépe nicméně je třeba brát v úvahu „žravost“ některých knihoven typu Zend Framework, které si s pamětí starosti nedělají a alokují co mohou
- více o memory_limit direktivě/testu - open_basedir
- tato direktiva by měla nahradit safe_mod, který je zlem vždy a všude – direktiva open_basedir definuje, do kterých adresářů na fyzickém filesystému se PHP skripty dostanou a kam už ne
- v případě hostingového serveru nebo serveru s více uživateli, je správně nastavený open_basedir nezbytnost
- více o open_basedir direktivě/testu - post_max_size
- defaultně 8 MB, doporučená hodnota 256 K
- definuje jakou maximální velikost dat lze odeslat PHP skriptu pomocí metody POST – doporučená hodnota je zde poměrně nízká a lze o ni dosti polemizovat, vždy je třeba zvážit potřeby aplikace, příliš vysoká hodnota může znamenat možnost DoS útoku na server
- více o post_max_size direktivě/testu - register_globals
- defaultně off, doporučená hodnota off
- tuto direktivu snad není třeba ani popisovat – jedná se o historický pozůstatek z divokých dob PHP, zakázat vždy a všude – více o register_globals direktivě/testu - save_path
- tato direktiva (přesněji session.save_path) definuje cestu, kde se budou ukládat data uživatelských session – cesta by měla být mimo strukturu kořene webu (document root) a měla by mít vhodně nastavená oprávnění (aby si session nemohli číst ostatní uživatelé systému)
- více o save_path direktivě/testu - upload_max_filesize
- definuje jakou maximální velikost dat lze odeslat PHP skriptu pomocí nahrávacího (upload) formuláře – doporučená hodnota musí vycházet z potřeb konkrétní aplikace, obecně čím méně tím lépe
- více o upload_max_filesize direktivě/testu - upload_tmp_dir
- definuje cestu, kde se ukládají dočasně soubory, které jsou nahrávány na server pomocí formuláře – podobně jako direktiva save_path by měla být tato cesta mimo strukturu kořene webu a měla by mít vhodně nastavená oprávnění
- více o upload_tmp_dir direktivě/testu - user_id
- nejedná se o direktivu PHP ale proměnou skriptu, tato proměnná definuje ID uživatele systému pod kterým je PHP skript spuštěn a tento test upozorňuje na možné riziko spuštění skriptu privilegovaným/systémovým uživatelem
- více o file_uploads testu
Popsané výchozí nastavení se vždy nemusí shodovat v vašim výchozím nastavení, některé distribuce a operační systémy a některé verze PHP si nastavují tyto hodnoty různě.
Před nastavením dané proměnné je vždy také třeba zvážit, zda bude server či VirtualHost pro více projektů/uživatelů. Důležité je také zvážit, jestli nasazení omezujících pravidel v podobě změn PHP direktiv neovlivní současné projekty na serveru, které by se pak museli předělat vzhledem ke změně nastavení. Proto je vhodné použít kombinaci jak globálních nastavení v php.ini
, tak lokálních pomocí ini_set(...)
či htaccessu
.
Závěr
Bohužel, projekt PhpSecInfo už je přes dva roku opuštěn (poslední verze je z 2007/04/06) a těžko říci, zda kdy bude ještě aktualizován. Myslím že je to škoda, protože stále vznikají nové a nové hrozby, přidávají se nové konfigurační direktivy (a některé se ruší) a pro začínajícího ale i pokročilého administrátora mohl být projekt dobrým zdrojem informací a inspirace.
Komentáře nejsou povoleny