PHP seadistamine

From ICO wiki
Jump to navigationJump to search

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"