Instalación como un binario CGI
Posibles ataques
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_
Caso 1: sólo se sirven archivos públicos
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)_
Caso 2: uso de __enable_force_cgi_redirect
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_
Caso 3: configuración de doc_root o user_dir
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_
Caso 4: intérprete PHP por fuera del árbol web
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_