PHP seadistamine
PHP seadistamine
Autor
Elar Lang
AK32
Sissejuhatus
Acunitex nimeline turbega tegelev firma andmetel (http://www.acunetix.com/blog/web-security-zone/articles/statistics-from-the-top-1000000-websites/) on 2010 aasta alguse seisuga 68% veebiserverites Apache ning 70% veebiserverites PHP. Serverite hooldamise ja PHP rakenduste kirjutamise vahele jääb oluline osa - PHP seadistamine ja rakendusele õigete õiguste määramine. Kuna arendaja võib pidada seda administraatori tööks ning administraator omakorda arendaja tööks, siis võib selle töö tegemise (st tegemata jätmise) juures tekkida oluline turvarisk. Antud kirjatüki eesmärk on juhtida tähelepanu olulisematele nüanssidele PHP seadistuse juures.
PHP seadistamine - mida jälgida
.. teise nurga alt vaadatuna - mis on enamlevinud ämbrid PHP veebikeskkonna seadistamisel?
Veateated
Kuvamine
Toodangukeskkonnas ei tohi mitte mingil juhul kuvada välja tarkvara poolt tekkinud vigade veateateid. See annab ründajale olulist infot rakenduse ülesehituse kohta ning lihtsustab rünnaku teostamist. Arenduskeskkonnas (ja ka test keskkonnas) peaks aga veateateid kuvama.
php manual: http://ee.php.net/manual/en/errorfunc.configuration.php#ini.display-errors
php.ini (vaikeväärtus):
display_errors = 1
php.ini (võiks olla):
display_errors = 0
runtime (seade määramine jooksvalt php koodis):
ini_set('display_errors', 0); // hide errors //ini_set('display_errors', 1); // show errors
See ei kuulu küll otseselt PHP seadistamise juurde, kuid reegel peaks ka olema, et programmikood ise ei kuva veateateid välja - näiteks, kui tekib viga SQL päringu teostamisel, siis ei tohi seda mitte mingil toodangu keskkonnas juhul välja kuvada (lihtsustab näiteks SQL injection rünnakute teostamist).
Logimine
Kõik tekkinud vead tuleb kindlasti maha logida, et vajadusel otsida tekkinud vigae põhjuseid (ja põhjustajaid). Veateadete logi tuleks ka jälgida, mitte lihtsalt logida.
php manual: http://ee.php.net/manual/en/errorfunc.configuration.php#ini.log-errors
php.ini (vaikeväärtus):
log_errors = 0
php.ini (võiks olla):
log_errors = 1
Detailsus
Veateateid tuleks tuvastada võimalikult suure detailsusega. Kindlasti mitte ignoreerida E_NOTICE taseme vigu, sest ka need näitavad välja koodi nõrkuseid või vigu (koodis tekib situatsioon, mida arendaja pole ette näinud).
php manual: http://ee.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting Eeldefineeritud detailsuse konstandid: http://ee.php.net/manual/en/errorfunc.constants.php
php.ini (vaikeväärtus):
error_reporting = E_ALL
Kuni PHP 5.2'ni E_ALL ei sisaldanud E_WARNING teateid. Alates PHP 5.3'st E_ALL raporteerib kõiki teateid peale E_STRICT teadete. Alates PHP 6'st on E_ALL teadete hulgas ka E_STRICT teated. Tasub jälgida PHP dokumentatsiooni. "error_reporting" väärtust saab määrata ka numbrina, igal konstandil on oma numbriline väärtus. Kuid kuna see number võib erinvate PHP versioonide puhul tähendada erinevaid asju (nt E_ALL puhul), siis on turvalisem kasutada selleks ikkagi nimelisi konstante.
php.ini (võiks olla):
error_reporting = E_ALL ~ E_STRICT
runtime (seade määramine jooksvalt php koodis):
error_reporting(E_ALL ~ E_STRICT);
Failide halduse ja üles laadimise seadistus
open_basedir
open_basedir parameeter määrab, millistest kataloogidest võib rakendus faile avada. Vaikimisi on väärtus määratama, mis tähendab, et rakendus saab faile avada tervest serverist (kui failide õigustega seda ei ole piiratud). Selle parameetri puudumine annab võimaluste teostada LFI (Local File Include) ründeid kogu failisüsteemi ulatuses.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.open-basedir
php.ini (vaikeväärtus):
open_basedir =
open_basedir vaikeväärtus PHP's puudub, st PHP poolt mingeid piiranguid ei ole (loevad vaid failiõigustest tulenevad piirangud).
php.ini (võiks olla):
open_basedir = /path/to/application/root/
Väga mugav oleks määrata open_basedir väärtuseks "." (ehk siis see sama kataloog, kus skript käivitatakse). See on aga ohtlik, kuna PHP chdir käsuga saab "aktiivse kataloogi" ja seega ka selle "." tähendust muuta. Jälgida tuleks väärtuse (või väärtuste) määramisel, et vajalikele kataloogidele ligipääs alles jääks (nt kui ei ole muudetud upload_tmp_dir väärtust, siis lisada open_basedir väärtusele ka /tmp kataloog).
Saab määrata ka httpd.conf failis (ja ka .htaccess failis):
<IfModule mod_php5.c> php_admin_value open_basedir /path/to/application/root/ </IfModule>
NB! määrates open_basedir piirangu httpd confi kaudu, ei rakendu see siis kui php käivitada käsurealt (ehk siis kui rakendus ise on juba turvaauguga ja saab tekitada käivitatava php koodi rakenduse alla, siis saab sellest piirangust mööda).
allow_url_fopen
Selle parameetriga juhitakse, kas failide avamise funktsioonidel on õigus avada fail üle urli. Kui rakendus sellist võimalust ei vaja, peaks selline võimalus olema keelatud (et välistada RFI (Remote File Include) rünnakuid).
php manual:http://ee.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen
php.ini (vaikeväärtus):
allow_url_fopen = 1
Vaikeväärtusena on üle urli failide avamine lubatud.
php.ini (võiks olla, kui rakendus ei vaja failide avamist üle urli):
allow_url_fopen = 0
file_uploads
Parameetriga juhitakse, kas HTTP failide üles laadimine on toetatud. Kui rakenduse funktsionaalsus seda võimalust ei vaja, peaks see olema keelatud.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.file-uploads
php.ini (vaikeväärtus):
allow_url_fopen = 1
Vaikeväärtusena on üle urli failide avamine lubatud.
php.ini (võiks olla, kui rakendus ei vaja failide üles laadimist):
allow_url_fopen = 0
upload_tmp_dir
Asukoht üles laetavate failide ajutiseks talletamiseks, kuni PHP programm nendega tegeleb. Pärast pöördumist tmp kataloogist failid kustutatakse.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.file-uploads
php.ini (vaikeväärtus):
upload_tmp_dir =
Vaikeväärtusena on määramata, kasutatakse süsteemi vaikeväärtust (mis linuxi puhul on /tmp kataloog)
php.ini (võiks olla, kui rakendus ei vaja):
upload_tmp_dir = /path/to/application/root/tmp
upload_tmp_dir parameetri väärtus ei tohiks kindlasti olla avalikku veebi paistev kataloog (st ei tohi olla "document_root" alamkataloog). Vaikeväärtus võiks olla muudetud, kuna failide üleslaadimine on ka üks DoS (Denial of Service) ründemeetodeid. Koormatakse veebiserverit lõputute failide üleslaadimistega, veebiserver tekitab iga faili jaoks "upload_tmp_dir" parameetriga kataloogi ajutisi php* nimelisi faile. Kui DoS rünnaku peale veebiserver kokku jooksis, siis võib tekkida olukord, kus tmp kataloogi jäävad need üles laetud ajutised failid alles. Samal ajal LFI (Local File Include) ründevõimalust omades saab ründaja niimoodi sokutada endale vajaliku koodi veebiserverisse.
upload_max_filesize
Maksimaalne ühe üles laetava faili suurus.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.upload-max-filesize
php.ini (vaikeväärtus):
upload_max_filesize = 2M
php.ini (võiks olla, vastavalt rakenduse vajadustele):
upload_tmp_dir = 2M
Väärtus peaks olema valitud rakenduse iseloomust (kui suuri faile ei oodata, ei ole seda hea ka seadistuses lubada).
max_file_uploads
Maksimaalne ühe päringuga üles laetavate failide arv.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.max-file-uploads
php.ini (vaikeväärtus):
max_file_uploads = 20
php.ini (võiks olla, vastavalt rakenduse vajadustele):
max_file_uploads = 1
Väärtus peaks olema valitud rakenduse iseloomust (kui mitme faili korraga üles laadimist ei oodata, siis ei ole seda hea ka seadistuses lubada).
post_max_size
Maksimaalne postituse suurus. See ei ole nüüd otseselt failide üles laadimise parameeter, kuid üldjuhul rakendub see piirang just failide üles laadimisele. Valitud väärtus ei tohiks olla põhjendamatult suur. Kui file_uploads parameetriga on failide üles laadimine välja lülitatud, siis lihtsalt vormide täitmise kaudu eriti mahukaid postitusi lubama ei peaks.
php manual: http://ee.php.net/manual/en/ini.core.php#ini.post-max-size
php.ini (vaikeväärtus):
post_max_size = 8M
php.ini (võiks olla vastavuses rakenduse reaalsete vajadustega):
post_max_size = ?
Kui kasutatakse failide üles laadimist, siis peaks post_max_size olema suurem kui "upload_max_filesize * max_file_uploads"