Instalado como CGI binarioAtaques posibles
Usar PHP como un binario CGI es una opción para
configuraciones que por alguna razón no desean integrar PHP como un
módulo dentro del software de servidor (como Apache), o usarán PHP con
diferentes tipos de envoltorios CGI para crear entornos
seguros chroot y setuid para scripts. Esta configuración usualmente involucra la instalación
del binario ejecutable de PHP en el directorio cgi-bin del servidor web. La recomendación
CA-96.11 del CERT recomienda
que está en contra de colocar cualquiera de los intérpretes dentro de cgi-bin. Aún si
el binario de PHP puede ser usado como un intérprete independiente, PHP está diseñado
para prevenir los ataques que esta configuración hace posible:
Accediendo a los ficheros del sistema: http://mi.servidor/cgi-bin/php?/etc/passwd
La consulta de información en una URL después del signo de interrogación (?) es
pasado como argumento de la línea de comandos al intérprete por la interfaz
del CGI. Usualmente los intérpretes abren y ejecutan el fichero
especificado como el primer argumento en la línea de comandos.
Cuando es invocado como un binario de CGI, PHP se rehusa a interpretar los
argumentos de línea de comandos.
Accediendo a cualquier documento web en el servidor: http://mi.servidor/cgi-bin/php/directorio/secreto/doc.html
Parte de la ruta de información de la URL después del nombre del binario de PHP,
/directorio/secreto/doc.html es
convencionalmente utilizado para especificar el nombre del fichero
a ser abierto e interpretado por el programa CGI.
Usualmente las directivas de configuración de algunos servidores web (Apache:
Acción) son utilizados para redirigir peticiones a los documentos como
http://mi.servidor/directorio/secreto/script.php al
intérprete de PHP. Con esta configuración, el servidor web revisa primero
los permisos de acceso a los directorios /directorio/secreto, y después crea la
petición redirigida http://mi.servidor/cgi-bin/php/directorio/secreto/script.php.
Desafortunadamente, si la petición es proporcionada originalmente en esta forma,
no se revisan los accesos a los directorios hechos por el servidor web /directorio/secreto/script.php, sino solamente al fichero
/cgi-bin/php. De esta forma
/cgi-bin/php cualquier usuario está habilitado a acceder
a cualquier documento protegido en el servidor web.
En PHP, las directivas de configuración en tiempo de ejecución cgi.force_redirect, doc_root y user_dir pueden ser utilizadas para prevenir
este ataque, si el árbol de documentos del servidor tiene cualquiera de estos directorios
con restricciones de acceso. Véase más abajo para una explicación completa
de las diferentes combinaciones.
Caso 1: Ficheros públicos servidos solamente
Si su servidor no tiene ningún contenido que no esté restringido
por contraseña o control de acceso basado en IP, no hay necesidad de
estas opciones de configuración. Si su servidor web no le permite
hacer redirecciones, o el servidor no tiene una forma de
comunicar al binario de PHP que la petición es una forma segura de
petición de redireccionamiento, puede especificar la opción --enable-force-cgi-redirect
para el script de configuración. Usted todavía tiene que asegurarse que sus
scripts de PHP no confían en una forma o en otra para llamar el script,
ni directamente http://my.host/cgi-bin/php/dir/script.php
ni por redirección http://my.host/dir/script.php.
La redirección puede ser configurada en Apache utilizando directivas
Action y AddHandler (vea más abajo).
Caso 2: utilizando cgi.force_redirect
La directiva de configuración cgi.force_redirect
previene a cualquiera que llame a PHP
directamente por medio de una URL como esta http://mi.servidor/cgi-bin/php/directoriosecreto/script.php.
En cambio, PHP solamente lo analizará en este modo si éste se ha ido a través de
una regla directa del servidor web.
Las versiones de PHP antiguas a la versión 4.2.0 utilizaban --enable-force-cgi-redirect
en opción de tiempo de compilación para esto.
Usualmente la redirección en la configuración de Apache se hace con
las siguientes directivas:
Esta opción ha sido probada solamente con el servidor web Apache, y
se basa en que en Apache se configure en una variable de entorno no-estándar de CGI
REDIRECT_STATUS para peticiones de redirección. Si su
servidor web no soporta ninguna forma de decirle si la petición es
directa o redirigida, usted no puede utilizar esta opción y debe usar
una de las otras formas de ejecutar la versión CGI aquí documentadas.
Caso 3: Configurando doc_root o user_dir
Para incluir contenido activo, como scripts y ejecutables, en los
directorios de documentos del servidor web es algunas veces considerado una práctica
insegura. Si, por el hecho del algún error de configuración, los scripts
no se ejecutan y son mostrados como documentos HTML regulares, esto
podría resultar en una fuga de información de propiedad intelectual
o de información de seguridad como las contraseñas. Por lo tanto muchos Administradores de Sistemas
preferirán configurar otra estructura de directorios para scripts que sean
accesibles solamente a través del CGI de PHP, y por lo tanto siempre interpretado y no desplegado como tal.
También si el método para asegurar las peticiones no es
redirigido, como se describió en la sección anterior, no está
disponible, es necesario configurar un script doc_root que sea
diferente de la raíz del documento web.
Usted puede configurar el script de la raíz de documento de PHP en la directiva
de configuración doc_root en el
fichero de configuración, o
puede configurar la variable de entorno PHP_DOCUMENT_ROOT.
Si éste es configurado, la versión del CGI
de PHP siempre construirá el nombre del fichero para abrir con este
doc_root y la ruta de información en la petición,
de tal forma que pueda estar seguro que ningún script será ejecutado fuera de
este directorio (excepto por user_dir que se encuentra
más abajo).
Otra opción utilizable es esta user_dir. Cuando user_dir no está configurado,
lo único que controla el fichero abierto es doc_root.
Al abrir una URL como http://mi.servidor/~usuario/documento.php no resulta
en la apertura de un fichero bajo el directorio personal de los usuarios, pero si
un fichero llamado ~usuario/documento.php debajo de
doc_root (si, un nombre de directorio que inicia con una a tilde [~]).
Si user_dir es configurado, por ejemplo public_php, una petición como http://mi.servidor/~usuario/doc.php abrirá un
fichero llamado doc.php bajo el directorio
llamado public_php debajo de el directorio
personal del usuario. Si el directorio personal del usuario es /home/usuario, el fichero ejecutado será
/home/user/public_php/doc.php.
La expansión de user_dir sucede sin tomar en cuenta
la configuración de doc_root, así que usted puede
controlar el acceso a la raíz de los documentos y el directorio de los
usuarios separadamente.
Caso 4: El analizador de PHP fuera del árbol de la web
Una opción muy segura es poner el binario analizador de PHP en algún lugar
fuera del árbol de ficheros de la web. En /usr/local/bin, por ejemplo. El único inconveniente
real con esta opción es que ahora tendrá que poner una línea similar a:
como la primera línea de cualquier fichero que contenga etiquetas de PHP. También
necesitará hacer que el fichero sea ejecutable. Eso significa, tratarlo exactamente
como trataría cualquier otro script de CGI escrito en Perl, sh, bash, o cualquier
otro lenguaje común de script el cual utilice #! como mecanismo
de ejecución de si mismo.
Para que PHP maneje la información correctamente de PATH_INFO y
PATH_TRANSLATED con esta configuración, el analizador de PHP debería ser
compilado con la opción de configuración --enable-discard-path.