A PHP CGI futtatható állományként való használata egy telepítési lehetőség azok számára, akik valami oknál fogva nem szeretnék a PHP-t modulként a szerverbe integrálni (pl. Apache), vagy a PHP-t más CGI wrapper-ekkel szeretnék használni biztonságos chroot és setuid környezet kialakítása érdekében. Ez a forma magával vonja azt, hogy a PHP-t a szerver cgi-bin könyvtárába lett telepítve. A CERT advisory CA-96.11 azt tanácsolja, hogy ne tegyél feldolgozó programot a cgi-bin könyvtárba. Bár a PHP használható mint egy egyedülálló feldolgozó program, a PHP-t úgy tervezték, hogy az ilyen telepítésekből adódó támadásokat kivédje:
Rendszerfájlok elérése: http://domain.nev/cgi-bin/php?/etc/passwd
Az URL lekérési információja (query information), ami a kérdőjel (?) után található, parancssori paraméterként kerül átadásra a feldolgozónak. Általában a feldolgozók megnyitják, és lefuttatják az első paraméterként adott fájlt.
Ha a PHP CGI futtatható állományként hívódik meg, nem veszi figyelembe a parancssori paramétereket.
Bármilyen web dokumentum elérése a szerveren: http://domain.nev/cgi-bin/php/titkos/doc.html
Az elérési út információ (path information) az URL része, a futtatható fájl neve után lévő /titkos/doc.html a CGI program által megnyitásra és futtatásra kerülő fájl elérésének meghatározására használatos. Tipikusan néhány webkiszolgáló beállítási lehetőség (Apache-ban: Action) használatos a kérések átirányítására a dokumentumhoz, mint a http://domain.nev/titkos/szkript.php a PHP értelmező számára. Ezzel a beállítással a szerver először ellenőrzi az elérési engedélyeket a /titkos könyvtárra, és ezután állítja elő az átirányító kérést a http://domain.nev/cgi-bin/php/titkos/szkript.php oldalra, amit így már a PHP feldolgoz. Azonban ha eredetileg is ebben a formában volt megadva a kérés, nem történik elérési ellenőrzés a /titkos/szkript.php fájlra, csak a /cgi-bin/php fájlra. Ilyen módon bárki, aki elérheti a /cgi-bin/php címet, egyben tetszőleges védett dokumentumot is elérhet.
A PHP esetében az --enable-force-cgi-redirect fordítási paraméter, a doc_root és user_dir konfigurációs lehetőségek használhatóak ennek kivédésére, ha a szerver dokumentumainak könyvtárfájában van olyan könyvtár, ami elérési korlátozásokkal bír. Nézd meg az alábbi lehetőségeket a különböző kombinációkhoz!
Ha a szerveren nincs olyan tartalom, ami jelszó vagy IP alapú védelemmel van ellátva, nincs szükség ezekre a konfigurációs beállításokra. Ha a kiszolgáló nem engedélyezi az átirányításokat, illetve ha nincs módja biztonságos átirányítással küldeni a kérést a PHP számára, megadhatod az --enable-force-cgi-redirect opciót a "configure" szkript számára. Meg kell győződnöd arról, hogy a PHP szkriptjeid nem függnek egy speciális szkript-hívási formától sem, mint a http://domain.nev/cgi-bin/php/dir/szkript.php vagy a http://domain.nev/dir/szkript.php.
Az átirányítás beállítása Apache alatt az AddHandler és Action direktívákkal történik (lásd lentebb).
Ez a fordítási paraméter megakadályozza, hogy bárki meghívja a PHP-t egy http://domain.nev/cgi-bin/php/titkos/szkript.php. URL-el. Ehelyett a PHP csak akkor fog elfogadni egy ilyen kérést ha egy szerver átirányításban kapta.
Apache esetében tipikusan a következő direktívákkal történik a beállítás:
Action php-script /cgi-bin/php AddHandler php-script .php |
Ez a lehetőség csak az Apache web szerverrel tesztelt és azon múlik, hogy az Apache beállítja a nem standard REDIRECT_STATUS CGI környezeti változót ha átirányított kérésről van szó. Ha a webkiszolgálód semmilyen módon nem közli, hogy ez egy direkt vagy átirányított kérés volt-e, nem használhatod ezt az opciót, így valamelyik másik módot kell használnod.
Aktív tartalom elhelyezése a normál dokumentumok között, (pl. szkriptek és futtatható állományok) veszélyes gyakorlat lehet. Ha például valamilyen beállítási hiba miatt a szkriptek ahelyett, hogy lefutnának hagyományos HTML dokumentumokként jelennek meg, mindenki számára tisztán látható válnak kódolási technikáid és pélsául adatbázis jelszavaid. Ezért néhány rendszeradminisztrátor inkább egy külön könyvtárat jelöl ki, ami csak a PHP CGI által elérhető, és így mindig feldolgozásra kerül és nem jelenik meg a szkript kódja.
Ha a fent leírt átirányítás azonosítási mód nem működik, fontos, hogy egy különálló szkript doc_root-ot határozz meg, ami nem azonos a web doc_root-al.
A PHP szkript dokumentumok gyökérkönyvtárát a doc_root konfigurációs beállítással határozhatod meg a konfigurációs fájlban, vagy a PHP_DOCUMENT_ROOT környezeti változóban adhatod meg ezt az értéket. Ha ez be van állítva a PHP CGI verziója a fájl elérési útját a doc_root és a kérés elérési út információja (path information) alapján állítja elő, ami azt jelenti, hogy ezen a könyvtáron kívül nem futtatható fájl. (kivéve a user_dir esetét).
Egy másik itt használható opció a user_dir. Ha ez nincs megadva, csak a doc_root szabályozza a megnyitható fájlok körét. Ekkor egy http://domain.nev/~user/doc.php URL nem a "user" nevű felhasználó home könyvtárában lévő fájlt keresi, hanem a ~user/doc.php fájlt keresi a doc_root alatt (igen, egy tilde karakterrel kezdődő könyvtárban [~]).
Ha a user_dir meg van adva, például public_php, akkor a fenti http://domain.nev/~user/doc.php kérés a doc.php nevű fájlt fogja megnyitni a "user" nevű felhasználó home könyvtárában lévő public_php könyvtárban. Ha a "user" home könyvtára /home/user, a lefuttatandó fájl a /home/user/public_php/doc.php lesz.
A user_dir kifejtés a doc_root beállítástól függetlenül működik, úgyhogy a dokumentum gyökér és felhasználói könyvtár beállításokat külön is használhatod.
Rendkívül biztonságos lehetőség a PHP feldolgozót valahol a webről látható könyvtárakon kívülre tenni. Például az /usr/local/bin könyvtárba. Az egyetlen igazi hátránya ennek az opciónak az, hogy minden PHP szkript első sorának egy ehhez hasonló sort kell megadnod:
ami meghatározza, hogy hol található a PHP feldolgozó, ami lefuttatja majd ezt a kódot. Ráadásul minden PHP szkriptnek futási jogot kell adni. Azaz úgy kell eljárni, mint bármilyen más nyelven megírt CGI programmal, amit Perl, sh vagy és a #! shell-escape mechanizmust használja önmaga futtatására.Ahhoz, hogy ebben az esetben a PHP helyesen kezelje a PATH_INFO és a PATH_TRANSLATED információkat, a PHP feldolgozót az --enable-discard-path "configure" paraméterrel kell fordítani.