Hardening PHP desde php.ini

6.11.09

Hardening, Asegurando nuestro PHP.ini

Vamos asegurar el PHP cambiando ciertos parámetros desde el php.ini.

Safe Mode

El "PHP safe mode" intenta resolver el problema de seguridad de servidores compartidos. Safe mode verifica el dueño de un archivo, si tienes una pagina test1.php que lee el contenido del directorio fotos/. Safe mode revisa el UID de test1.php y del directorio fotos/. Si estos concuerdan es permitido el script de php, en caso contrario safe mode desactivara el acceso. Este tipo de seguridad es interesante para restringir el acceso a los scripts fuera del directorio normal de la aplicacion.

Safe mode causa problemas cuando el web server es dueño de los archivos, por ejemplo cuando se sube un nuevo archivo o es creado por la aplicacion usualmente el dueño es "httpd", "apache" o una cuenta similar.

Safe mode tambien restringe los ejecutables que corren scripts de la misma manera, restringiendo archivos y acessos a los directorios.

Para habilitar la directiva de safe mode:

safe_mode = On

Si quieres limitar los directorios que puedan contener archivos include o ejecutables, usa esta directiva en el php.ini:

safe_mode_include_dir = /direc/to/rio
safe_mode_exec_dir = /direc/torio/exec


Nota: Safe mode sera eliminado en futuras versiones.

Restringir Includes

Usando la directiva de open_basedir en PHP nos evitamos ciertos problemas. Esta directiva limita el directorio a ser usado para incluir archivos. Por ejemplo se puede incluir archivos locales en el script de PHP para ser mostrados a través de la web. En el cual un atacante puede incluir /etc/passwd para ver todos las cuantas de usuarios en el sistema. Con la directiva open_basedir se puede restringir a un directorio, como /var/www. Un archivo fuera del directorio no podrá incluirse, y el ataque fallaría. Habilitar el open_basedir modifique la linea e incluya su directorio.

open_basedir = /direc/torio/web


Desabilitando Funciones.

Hay algunas funciones que los desarroladores no deberian usar ya que son muy peligrosas. Si esta seguro de que ciertas funciones no se estan usando es mejor deshablitarlas para evitar que los atacantes la usen. Este tipo de seguridad  es muy efectiva para los atacantes que de alguna manera suben scripts de PHP al servidor. Deshabilitando ciertas funciones puede limitar la efectividad de estos tipos de ataques.

Desabilitando funciones como shell_exec() y system() puede prevenir que usuarios y atacantes las usen, ya que son vulnerabilidades potenciales para ejecutar código remoto. Lo mejor es que los desarrolladores usen las mínimas funciones disponibles y deshabilitar el resto. Ya que no es una solución efectiva pero puede prevenir ataques como la shell c99 o r57 ya que son muy temidos por su poder, ya que tienen toda una consola de tu servidor via web asi de sencillo. Para deshablilitar estas funciones y otras simplemente agregue las funciones separadas por comas en el php.ini como en el siguiente ejemplo:

No tan restrictiva.
disable_functions = php_uname, getmyuid, getmypid, passthru, leak, listen, diskfree, system, shell_exec

Restrictiva. (Recomendada)
disable_functions = exec, system, ini_set, show_source, shell_exec, passthru, phpinfo, popen, proc_open, allow_url_fopen, dl, define_syslog_variables

Mas restrictiva.
disable_functions = exec, system, ini_set, show_source, shell_exec, passthru, phpinfo, popen, proc_open, allow_url_fopen, curl_exec_multi_exec, parse_ini_file, php_uname, getmyuid, getmypid, leak, listen, disk_free_space, error_log, ini_alter, dl, pfsockopen, openlog, syslog, readlink, symlink, link, escapeshellcmd, proc_close, proc_get_status, proc_nice, proc_terminate, escapeshellarg, pcntl_exec, define_syslog_variables

Muy Restrictiva
disable_functions = exec, system, ini_set, show_source, shell_exec, passthru, phpinfo, popen, proc_open, allow_url_fopen, curl_exec_multi_exec, parse_ini_file, php_uname, getmyuid, getmypid, leak, listen, disk_free_space, error_log, ini_alter, dl, pfsockopen, openlog, syslog, readlink, symlink, link, escapeshellcmd, proc_close, proc_get_status, proc_nice, proc_terminate, escapeshellarg, pcntl_exec, posix_mkfifo, ini_restore, symlink, apache_child_terminate, curl_multi_exec, mysql_pconnect, define_syslog_variables, ftp_connect, highlight_file, posix_getpwuid, posix_uname, posix_kill

Nota: Intentar que los desarrolladores estandaricen unas funciones. En otras palabras deshabilitar la mayoría de las funciones y tener habilitadas solo aquellas que se esten usando.

Prevenir Mostrar Información.

Los atancantes pueden usar la informacion que el servidor web muestra para tener informacion sobre la configuracion del servidor, las aplicaciones y componentes. Los mensajes de error es lo mas comun para obtener informacion, donde se puede ver informacion relativa del directorio de instalacion, conectividad con la base de datos, tablas, nombres de columnas y ciertos scripts donde muestran las variables. Mientras que esta informacion la usan los desarroladores para acomodar su sistema, es peligroso que lo vean los atacantes. Mostar los errores se tiene que desahabilar, de hace de la siguiente manera:

display_errors = Off

Este evitara que PHP muestre los errores por medio de la pagina a los usuarios. PHP registrara los errores de forma normal, para que pueda ser revisado por los desarroladores. Tenga en cuenta que algunos desarroladores pueden usar herramientas de terceros como FirePHP, comentarios en HTML, o usar .htaccess y la directiva de error_log. Impedir que se vean los errores puede reducir la posibilidad de ataques por exponer información.

Deshabilitar Variables Globales

Las variables globales ya no sera soportada para futuras versiones, por obvias razones. Busque la siguiente linea en el php.ini para deshabilitarlas:

register_globals = Off

Deshabilitar Remote File Includes (RFI)

Los atacantes intentaran buscar esta vulnerabilidad en la aplicacion para poder incluir scripts PHP daninos. Incluso si el atacante no tiene acceso al directorio de la aplicacion web pero la "inclusion de archivos remota" esta habilitada, el atacante puede guardar el codigo en otro servidor y la aplicacion web de nosotros lo buscara y lo ejeutara localmente. Asegurese de tener las siguientes opciones deshabilitadas:

allow_url_fopen = Off
allow_url_include = Off


Esto evitara que los scripts sean incluidos y ejecutados en el sistema de nosotros.


Restringir Subir Archivos

Si esta opcion no la esta utilizando es buena idea que la deshabilite. Un atacante podría usarlo inyectando scripts en su aplicación web. Deshabilitar file uploads hará mas difícil introducir algún script dentro de su servidor web. Para deshabilitarlo cambie la siguiente linea en el php.ini:

file_uploads = Off

Si esta permitido file uploads debería cambiar el directorio temporal que usa esta directiva. Ademas también debería cambiar el tamaño de archivo a subir. Esto no es seguridad propiamente dicha pero puede ser útil. Para cambiar el directorio y el tamaño de los archivos a subir, vea la siguiente linea:

upload_tmp_dir = /var/temporal_php
upload_max_filesize = 1M



Proteger Sesiones

Robar sesión es un ataque muy popular que permite a un usuario hacer hijack en la sesión de un usuario legitimo. Este tipo de atacaque permite al usuario pasar los accesos de la aplicacon web sin pedir autorizacion. El problema del sistema de sesiones es que el identificador de la sesion es escrito en el sistema de fichero en el momento que son creados y PHP hace un seguimiento de eso. Cambiar la ubicacion predeterminada de los identificadores de sesion puede evitar algunos intentos de leerlos.  Para cambiar la ubicación use la siguiente linea en el php.ini:

session.save_path = /var/session/php

Verifique que el servidor web puede leer y escribir en el directorio especificado. Ademas debería configurar PHP para que lea las cookies de una manera que no sea accesible por JavaScript. Un atacante podría explotar las fallas de Cross Site Scripting (XSS) en su pagina web inyectando código JavaScript, que puede ser usado para robar las cookies de sesión. Esta opción la puede modificar de la siguiente manera:

session.cookie_httponly = 1

Con esto evitara que JavaScript acceda a las cookies, Otra medida de seguridad es permitir que PHP verifique los valores de HTTP referer para que la información de la sesión se pase internamente cuando el usuario ve la pagina web. Esto evita a que algún usuario publique información de su sesión sin querer, permitiendo que un usuario mal intencionado siga el enlace y robe la sesión. Esto es útil cuando el URL se publica en foros, mail list, etc. Habilite esta función de la siguiente manera en el php.ini:

session.referer_check = tudominio.algo

magic_quotes_gpc

En PHP, magic_quotes_gpc es recomendado que se deshabilite para protegerse de inyección SQL. La mayoría de los frameworks espera que este en off y si esta habilitado puede dar problemas, esta opción ya esta en desuso y sera removido en PHP6. También es recomendada deshabilitarla por razones de rendimiento.

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off


expose_php

Cuando esta activado, expose_php reporta en cada petición que PHP se esta usando para procesarla y que versión se encuentra instala. Un atacante puede usar esto para identificar las debilidades. 

Esto no va a detener a un atacante por si mismo, pero si reduce la posibilidad evitando técnicas de reconocimiento de vulnerabilidades. Deshabilitelo de la siguiente manera:

expose_php = Off

Por ultimo y para finalizar, esto solo seria una parte de las medida de seguridad en su aplicación web, para incrementar la seguridad puede usar Suhosin. Recuerde que tiene que ser cuidadoso deshabilitando las opciones ya que esto evitara que su aplicación web funcione adecuadamente. Reinicie su servidor web para que los cambios tengan efecto.

Jhyx

2 comentarios:

Anónimo dijo...

Gracias por el artículo.

Aprovecho para indicar que hay una errata: la única diferencia entre las configuraciones "Más restrictiva" y "Muy restrictiva" de disable_functions es que la segunda repite lo siguiente: error_log, ini_alter, dl, pfsockopen, openlog, syslog, readlink, symlink, link, escapeshellcmd, proc_close, proc_get_status, proc_nice, proc_terminate, escapeshellarg, pcntl_exec.

Saludos,

Manuel

Jhyx dijo...

Hola,

Gracias no me habia dado cuenta, aqui estan las correcciones.

Corregido ini_net a ini_set
Corregido diskfree a disk_free_space
Agregado en Restrictiva: dl, define_syslog_variables
Agregado en Mas Restrictiva: define_syslog_variables
Agregado en Muy Restrictiva:
posix_mkfifo, ini_restore, symlink, apache_child_terminate, curl_multi_exec, mysql_pconnect, define_syslog_variables, ftp_connect, highlight_file, posix_getpwuid, posix_uname, posix_kill

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.