Anterior Siguiente Índice Cursillo de WWW: Seguridad Javier Fernández-Sanguino Peña ( jfs@dat.etsit.upm.es) v0.1,Fri Mar 20 13:35:56 CET 1998 Estas son las transparencias a utilizar en el cursillo para Webmasters durante el día de "Seguridad en la WWW" (Martes 24). Estas transparencias han sido realizadas con Linuxdoc-SGML. 1. Seguridad en la WWW: Introducción 2. Sobre servidores 2.1 Riesgos en la instalación de un servidor 2.2 Precauciones que se deben tener: 2.3 Qué cosas pueden causar problemas 3. Seguridad en CGI's 3.1 CGIs interpretados: Bash y Perl 3.2 CGIs compilados 4. Que nos quedaría por contar 5. Para terminar 6. Bibliografía 7. Apéndice Anterior Siguiente Índice 1. Seguridad en la WWW: Introducción Es necesario conocer conceptos de seguridad para evitar errores comunes a la hora de instalar un servidor. La mayor parte de los agujeros de seguridad son debidos a la inaecuada instalación y configuración. Un porcentaje muy bajo se debe a errores en los programas (salvo cuando hablamos de CGIs) Se van a introducir los riesgos, los problemas... para luego ver un caso particular: la Seguridad en CGI's Se recomienda poderosamente mantenerse al tanto de los problemas de seguridad (acudir a los servidores de la bibliografía) 2. Sobre servidores Estos son algunos de los aspectos de seguridad que están relacionados con cómo se ha instalado un servidor o se ha configurado. 2.1 Riesgos en la instalación de un servidor Un servidor de WWW es una puerta al mundo por la que se dan información y servicio para satisfacer una necesidad (del cliente), pero esta misma puerta puede ser forzada, y la información que se entreguen o los servicios que se den pueden no ser los deseados. Los riesgos de seguridad que se tratarán son: entregar desde el servidor de información privada o confidencial (que se supone no debería dar) esto incluye: ficheros de datos de la organización, bases de datos, ficheros de usuarios... acceso a información confidencial "capturándola" de la red, por ejemplo, números de tarjetas de crédito. acceso a información de la situación, configuración y acceso al servidor: ficheros con información del estado de la máquina, claves encriptadas de los usuarios.... ejecución remota de programas en el servidor. 2.2 Precauciones que se deben tener: Antes de instalar ningún programa para WWW (ni siquiera el servidor) asegurarse de que está bien instalado/configurado. Controlar el acceso al servidor (revisión rutinaria de logs en busca de ataques, hay programas como Tripwire que ayudan a hacerlo pero también conviene hacerlo a mano) Revisar los programas que se utilizan (CGI's) para comprobar que no pueden ser subvertidos. Controlar la información ofrecida por el servidor y no dejar que entregue más de la necesaria. Y algunas genéricas que se deben hacer en cualquier sistema (haya servidor de WWW o no): Limitar el número de usuarios en la máquina. Borrar usuarios inactivos. Hacer que la gente elija buenas passwords. Desactivar servicios no usados (finger,NIS,YP..) Comprobar los permisos del sistema 2.3 Qué cosas pueden causar problemas Hay algunos elementos del servidor que son especialmente sensibles y que pueden dar lugar a graves agujeros de seguridad que puedan ser aprovechados por cualquier atacante: CGI scripts (y todo lo que hay en éste directorio) Server side includes. Es muy desaconsejable activarla si no se utiliza o no se entiende Generación automática de directorios (pueden dar acceso a información sensible, ejemplo: acceso a ficheros de backup -emacs-, seguimiento de enlaces simbólicos..) Directorios mantenidos por usuarios: NUNCA dejar que los usuarios puedan poner CGIs de forma indiscriminada, ojo a los enlaces simbólicos... 3. Seguridad en CGI's Aquí analizaremos los problemas de seguridad que pueden surgir por la instalación de CGI's. Vamos a ver el caso particular de las máquinas UNIX, pero otros servidores (NT por ejemplo) tienen problemas de seguridad también muy importantes (llamadas a batch, acceso a SMB...) 3.1 CGIs interpretados: Bash y Perl El error más común en el desarrollo de CGI's es el uso de variables tomadas de la entrada (del formulario, de la llamada tipo GET o POST) para utilizarlas como opciones en la llamada a el programa para el que el CGI hace de interfaz. Los scripts en Bash y Perl se dan más a éste tipo de problemas porque la facilidad para hacerlos rápidamente (dirty prototiping) hace que no se revisen adecuadamente ¿Cuales son los problemas? Si está muy mal hecho se puede ejecutar cualquier programa en el servidor. El problema se agrava si se está ejecutando el servidor como root (ojo! aquí nos referimos a los hijos, el padre debe ser siempre ejecutarse como root para ligarse al puerto 80). Esto se debe a que la llamada al programa al que se liga el CGI suele hacerse en una subshell (en Perl:``, system (), exec (), eval, open (HANDLE, "shell |") u open (HANDLE, "| shell"); en Bash simplemente al ejecutar cualquier cosa (ya estamos en una shell). Ejemplillo: #!/usr/bin/perl # Uso http://..../cgi-bin/echo? # Manda el QUERY_STRING de vuelta al usuario $|=1; $in=$ENV{'QUERY_STRING'}; $in =~ s/%(..)/pack("c",hex($1))/ge; # Eliminar malos caracteres # Lista de CGI-security FAQ $in =~ s/([;<>\*\`&\$!#\(\)\[\]\{\}:'"])/\\$1/g; print "Content-type: text-html\n\n"; system ("/bin/echo $in"); # Debería ser 'system("/bin/echo";$in)' para que fueran opciones de la bash Accesos de entrada salida: open, unlink, rmdir, read (y ), print, sprintf, write... podríamos sobreescribir cosas que no deseamos. Cómo hacerlos más seguros En CGI's Perl SIEMPRE llamar a perltainted (#!/usr/bin/perl -T) para que se queje si se está mal usando los datos de entrada (todos los datos de entrada se convierten en 'tainted' y es necesario des-'taint'earlos explícitamente). Si se van a utilizar los datos de usuario buscar y eliminar caracteres que no deberían estar allí (;&""``\n.[]{}<>..) y que pueden causar problemas a las sub-shell. Por ejemplo: $entrada=~tr/+/ /; # Para traducir los espacios en blanco $entrada=~s/%([0-9a-Fa-f]{2})/pack("C",hex($1))/eg; # Pasamos los caracteres en códigos ASCII al caracter correspondiente $entrada=~tr/A-Za-z0-9//cd; # Nos quedamos sólo con lo alfanumérico Algunos servidores "ya curtidos" (Apache) hacen esto por nosotros, pero aunque lo hagan no está de más hacerlo nosotros. Limitar la entrada a lo que se desea (números, fechas...) y comprobar que se nos da eso (no fiarse NUNCA de la entrada) Revisar con lupa las llamadas a sub-shells. 3.2 CGIs compilados Los CGI's compilados (por ejemplo en C) además de sufrir los problemas de las llamadas a shell (aunque estos errores son menos comunes, principalmente porque se distingue bien en las llamadas cual es el programa y cual los parámetros, por ejemplo en un execve..), sufren, si la persona no codifica bien los errores de Buffer overflows (común a otros programas). Este último problema radica en que se ha dimensionado un buffer donde se van a acumular datos de entrada de un determinado tamaño pero luego nos pasan más datos de los esperados (por ejemplo hacer una asignación estática de un array de caracteres de 50 bytes y que luego nos pasen 51 bytes). La solución es fácil y pasa por tener cuidado al recibir la entrada y asignar el espacio de manera dinámica, no estática. 4. Que nos quedaría por contar Hay una serie de temas que no se van a contar por falta de tiempo y en aras a la concepción práctica de este cursillo, pero faltarían por abordar los siguientes temas (para más información acudir a la bibliografía Seguridad en applets Java (máquina virtual) y en Javascript. Seguridad en los navegadores (fallos de seguridad en IE) Encriptación, clave pública y clave secreta (SSL, SHTTP) Server side Includes (más en detalle) 5. Para terminar Para terminar sólo algunas ideas: no hay ningún servidor 100% seguro, pero no pasa nada por intentar hacerlo 100% seguro cuando se abre una puerta al exterior hay que tener cuidado de que no se cuelen ladrones los programas cuanto más complejos, más servicios .... los programas cuanto más complejos, más problemas.