Folosind PHP ca pe un binar CGI este o optiune pe care setup-urile, dintr-un anume motiv, nu doresc sa o configureze si sa o integreze in PHP ca pe un modul in serverul software (precum Apache), sau vor folosi PHP cu ajutorul diferitelor metode de CGI wrap pentru a crea medii securizate chroot si setuid pentru scripturi. Acest setup implica de obicei instalarea binarului PHP executabil in directorul cgi-bin din serverul web. Indrumarul CERT CA-96.11 nu recomanda plasarea oricarui tip de interpretor de acest gen in directorul cgi-bin. Chiar daca binarul PHP poate fi folosit ca un interpretor de sine statator, PHP a fost conceput in asa fel incat sa anticipeze atacuri generate de un asemenea setup:
Accesarea fisierelor din sistem: http://host.ext/cgi-bin/php?/etc/passwd
Informatia din URL de dupa semnul de intrebare (?) este pasata liniei de comanda ca argumente si interpretata de interfata CGI. De obicei interpretoarele deschid si executa fisierul specificat ca prim argument in linia de comanda.
Cand este apelat ca un binar CGI, PHP refuza sa interpreteze argumentele din linia de comanda.
Puteti accesa orice document de pe server: http://host.ext/cgi-bin/php/secret/doc.html
Informatiile introduse in URL dupa numele binarului PHP, /secret/doc.html sunt de obicei utilizate pentru a specifica numele si calea catre fisierul care trebuie deschis de catre interpretorul CGI. De obicei directivele din configuratia unui server web (Apache: Action) sunt folosite pentru a redirecta cererile catre documente ca http://www.host_victima.ro/secret/script.php catre interpretorul PHP. Cu acest setup, serverul web verifica mai intai permisiile de acces catre directorul /secret, si dupa aceea creaza cererea de redirectionare catre http://www.host.ro/cgi-bin/php/secret/script.php. Din pacate, daca cererea originala se face sub aceasta forma nu sunt facute nici un fel de verificari de catre serverul web catre fisierul /secret/script.php, ci numai pentru fisierul /cgi-bin/php. In acest fel, orice utilizator care poate executa /cgi-bin/php, poate accesa automat orice director sau fisier protejat de pe server.
In PHP, optiunea din timpul compilarii --enable-force-cgi-redirect si directivele de configuratie doc_root si user_dir pot fi folosite pentru a preveni acest atac, daca structura documentelor de pe server contine vreun director cu acces restrictionat. Observati mai jos explicatii detaliate despre diferite combinatii.
Daca serverul dumneavoastra nu are nici un fel de continut (directoare/fisiere) care este restrictionat prin parola sau pe baza de IP, atunci nu este nevoie de aceste configuratii. Daca serverul web nu da voie la redirectari, sau nu comunica cu binarul PHP pentru a-i transmite daca cererea este una sigura, puteti specifica optiunea --enable-force-cgi-redirect scriptului de configurare. Totusi trebuie sa va asigurati ca scripturile dumneavoastra PHP nu depind intr-un fel sau altul de modul in care este facuta cererea - direct http://my.host/cgi-bin/php/dir/script.php sau prin redirectie http://my.host/dir/script.php.
Redirectarea poate fi configurata in Apache folosind directivele AddHandler si Action (vezi mai jos).
Aceasta optiune disponibila in timpul compilarii este folosita pentru a preveni rularea unui script PHP direct printr-un URL gen http://my.host/cgi-bin/php/secretdir/script.php. In schimb, PHP va actiona in acest mod numai dupa ce se va trece de regulile impuse de redirectionare din serverul web.
De obicei redirectarea in configuratia Apache se face dupa urmatoarele directive:
Action php-script /cgi-bin/php AddHandler php-script .php |
Aceasta optiune a fost testata numai cu serverul Apache, si se bazeaza pe setarea variabilei non-standard CGI REDIRECT_STATUS, pentru cererile de redirectionare. Daca serverul dumneavoastra nu suporta nici o metoda de a analiza daca o cerere este directa sau redirectata, nu puteti folosi aceasta optiune, si trebuie sa folositi alte cai descrise in subcapitolele de mai jos.
Includerea de continut activ, de pilda scripturi si executabile, in directoarele serverului web este de multe ori considerata o metoda nesigura. Daca, din cauza unor configuratii gresite, scripturile nu sunt executate ci afisate ca documente HTML, atunci securitatea sistemului si informatii vitale cum ar fi parolele pot fi desconspirate. De aceea multi administratori de sistem configureaza un director creat special, in care ruleaza scripturi accesibile numai via PHP CGI, deci care sunt interpretate tot timpul ca atare.
De asemenea daca metoda de transmitere a cererilor, descrisa mai sus, nu este disponibila, atunci este necesara configurarea unui director doc_root care este diferit de documentul web root.
Puteti configura documentul radacina al scripturilor PHP prin directiva doc_root din fisierul de configuratie, sau puteti configura variabila de mediu PHP_DOCUMENT_ROOT. Daca este setata, versiunea PHP pe care o detineti va constui intotdeauna numele fisierului deschis din doc_root si informatiile despre cale din cerere, pentru a fi siguri ca scriptul este executat in afara acestui director (exceptie facand user_dir de mai jos).
Alta optiune folosita este user_dir. Cand user_dir nu este configurat, singurul lucru care controleaza fisierul deschis este doc_root. Deschiderea unui URL ca http://my.host/~user/doc.php nu rezulta din accesarea unui fisier din directorul home al utilizatorilor, ci a unui fisier numit ~user/doc.php din doc_root (da, un director a carui nume incepe cu tilda [~]).
Daca user_dir este configurat spre exemplu ca public_php, o cerere in genul http://my.host/~user/doc.php va deschide un fisier numit doc.php din directorul numit public_php aflat sub directorul radacina al utilizatorului user. Daca directorul radacina al utilizatorului user este /home/user, fisierul executat este /home/user/public_php/doc.php.
Expansiunea user_dir se poate face fara a tine cont de paramentrul doc_root din setari, deci puteti controla accesul la directorul radacina si la directoarele utilizatorilor in mod separat.
O metoda foarte sigura si eleganta este de a plasa compilatorul PHP in afara directorului radacina web. In /usr/local/bin, spre exemplu. Singura dezamagire pe care o veti avea, este ca trebuie sa puneti urmatoarea linie:
la inceputul fiecarui fisier care contine taguri PHP. De asemenea va trebui sa faceti fisierul executabil. Acesta este tratat exact ca un script CGI scris in Perl sau sh sau orice alt limbaj de scripting care utilizeaza #! mecanismul shell-escape pentru a se lansa.Pentru ca PHP sa utilizeze informatiile PATH_INFO si PATH_TRANSLATED in mod corect, acesta trebuie compilat cu optiunea de configurare--enable-discard-path