El uso de PHP como un binario CGI es una
opción para el tipo de situaciones en las que por alguna
razón no se desea integrar PHP como módulo de
algún software de servidor web (como Apache), o en donde
se espera usar PHP con diferentes tipos de capas que envuelven el
entorno CGI para crear ambientes chroot y setuid seguros para la
ejecución de scripts. Esta configuración usualmente
involucra la instalación de un binario ejecutable del
intérprete PHP en el directorio cgi-bin del servidor
web. El aviso de seguridad de CERT CA-96.11 recomienda que se evite la
colocación de cualquier intérprete bajo
cgi-bin. Incluso si el binario PHP puede ser usado como un
intérprete independiente, PHP está diseñado
para prevenir el tipo de ataques que esta configuración
hace posible:
Acceso a archivos del sistema: http://mi.servidor/cgi-bin/php?/etc/passwd
La información del query en una URL, la cual viene
después del signo de interrogación (?), es pasada
como argumentos de línea de comandos al
intérprete por la interfaz CGI. Usualmente los
intérpretes abren y ejecutan el archivo especificado
como primer argumento de la línea de comandos.
Cuando es invocado como un binario CGI, PHP se rehúsa a
interpretar los argumentos de la línea de comandos.
Acceso a cualquier documento web en el servidor: http://mi.servidor/cgi-bin/php/zona_secreta/doc.html
El segmento de la URL que sigue al nombre del binario de PHP,
que contiene la información sobre la ruta /zona_secreta/doc.html es usada
convencionalmente para especificar el nombre de un archivo que
ha de ser abierto e interpretado por el programa
CGI. Usualmente, algunas directivas de
configuración del servidor web (Apache: Action) son
usadas para redireccionar peticiones de documentos
como http://mi.servidor/zona_secreta/script.php
al intérprete de PHP. Bajo este modelo, el servidor web
revisa primero los permisos de acceso al directorio /zona_secreta, y después de eso
crea la petición de redireccionamiento a http://mi.servidor/cgi-bin/php/zona_secreta/script.php.
Desafortunadamente, si la petición se hace originalmente
en esta forma, no se realizan chequeos de acceso por parte del
servidor web para el archivo /zona_secreta/script.php,
únicamente para el archivo /cgi-bin/php. De este modo, cualquier
usuario capaz de acceder a /cgi-bin/php es capaz también de
acceder a cualquier documento protegido en el servidor web.
En PHP, la configuración de tiempo de compilación
--enable-force-cgi-redirect
y las directivas de configuración en tiempo de
ejecución doc_root y
user_dir pueden ser usadas
para prevenir este tipo de ataques, si el árbol de
documentos del servidor llegara a tener directorio alguno con
restricciones de acceso. Consulte las siguientes secciones para
una explicación detallada de las diferentes
combinaciones.
Si su servidor no tiene contenido alguno que no esté
restringido por contraseñas o control de acceso basado en
direcciones ip, no hay ninguna necesidad de recurrir a estas
opciones de configuración. Si su servidor web no le
permite hacer redireccionamientos, o el servidor no tiene una
forma de comunicarle al binario PHP que la petición de
redireccionamiento es segura, puede especificar la opción
--enable-force-cgi-redirect
en el script de configuración. Aun así debe
asegurarse de que sus scripts PHP no dependan de alguna forma
especial de hacer llamados al script, ya sea directamente
mediante http://mi.servidor/cgi-bin/php/dir/script.php
ni por la redirección http://mi.servidor/dir/script.php.
Los redireccionamientos pueden ser configurados en Apache
mediante el uso de directivas AddHandler y Action (vea más
adelante).
Esta opción en tiempo de compilación previene que
cualquier persona haga llamados a PHP directamente mediante una
URL como http://mi.servidor/cgi-bin/php/directorio_secreto/script.php.
En lugar de esto, PHP analizará documentos de esta forma
únicamente si han pasado por una regla de
redirección del servidor web.
Por lo general, el redireccionamiento en la configuración
de Apache es realizada con alguna de las siguientes directivas:
Action php-script /cgi-bin/php
AddHandler php-script .php |
Esta opción ha sido probada únicamente con el
servidor web Apache, y depende de que Apache defina la variable
de entorno no-estándar REDIRECT_STATUS a la
hora de gestionar peticiones redirigidas. Si su servidor web no
dispone de modo alguno de comunicar si la petición es
directa o redirigida, no puede usar esta opción y debe
recurrir a alguna de las otras formas documentadas aquí de
ejecutar la versión CGI.
Incluir contenido activo en los directorios de documentos del
servidor web, como scripts y ejecutables, es considerada en
ocasiones una práctica insegura. Si, por algún
fallo de configuración, los scripts no llegaran a ser
ejecutados sino desplegados como documentos HTML normales, esto
podría resultar en la revelación de
información crítica como trabajos cubiertos por
normas de propiedad intelectual o datos de seguridad como
contraseñas. Por lo tanto muchos administradores de
sistemas preferirán la configuración de otra
estructura de directorios para los scripts que sean asequibles
únicamente a través del CGI PHP, y por lo tanto
deben ser interpretados siempre y no desplegados directamente.
Así mismo, si el método para asegurarse de que las
peticiones no son redireccionadas, tal y como se describió
en la sección anterior, no está disponible, es
necesario entonces configurar un directorio raíz
(doc_root) de scripts que sea diferente al directorio raíz
de documentos web.
Puede definir el directorio raíz para scripts de PHP
mediante la directiva de configuración doc_root en el archivo de
configuración, o puede darle un valor a la variable
de entorno
PHP_DOCUMENT_ROOT. Si ésta está
definida, la versión CGI de PHP construirá siempre
el nombre del archivo a abrir con
este doc_root y la información de
la ruta dada en la petición, de modo que puede estar
seguro de que ningún script será ejecutado por
fuera de este directorio (excepto por aquellos indicados en
user_dir, como se verá a
continuación).
Otra opción que puede ser usada en este caso es user_dir. Cuando user_dir no
está definida, lo único que controla la apretura de
archivos es
doc_root. Abrir una URL como http://mi.servidor/~usuario/doc.php no
resulta en la apertura de un archivo bajo el directorio personal
del usuario, sino de un archivo llamado ~usuario/doc.php bajo la ruta doc_root
(así es, un directorio cuyo nombre comienza por el
caracter de equivalencia [~]).
Si user_dir está definido como, por ejemplo, public_php, una petición
como http://mi.servidor/~usuario/doc.php
abrirá un archivo llamado doc.php
bajo el directorio con el nombre public_php ubicado en el directorio
personal del usuario. Si el directorio personal del usuario
es /home/usuario, el archivo
ejecutado es
/home/usuario/public_php/doc.php.
La expansión del valor de user_dir
ocurre independientemente del parámetro
doc_root, de modo que es posible controlar
el directorio raíz de los documentos y el acceso a los
directorios de los usuarios en forma separada.
Una opción bastante segura es colocar el intérprete
binario de PHP en alguna parte por fuera del árbol de
archivos web. En /usr/local/bin,
por ejemplo. El único inconveniente real con esta
alternativa es que ahora usted tendrá que colocar una
línea como esta:
al comienzo de cualquier archivo que contenga etiquetas
PHP. También tendrá que hacer cada archivo
ejecutable. Esto quiere decir que debe tratarlo exactamente igual
a como trataría cualquier otro script CGI escrito en Perl
o sh o cualquier otro lenguaje de scripting común que
usara el mecanismo de escape-shell
#! para el
lanzamiento del intérprete.
Para lograr que PHP gestione correctamente la información
de PATH_INFO y PATH_TRANSLATED con
este tipo de configuración, el intérprete PHP debe
haber sido compilado con la opción de configuración
--enable-discard-path.