lunes, 22 de octubre de 2012

MySql Guía de seguridad general


Guía de seguridad general

Cualquiera que utilice MySQL en un ordenador conectado a Internet debería leer esta sección para evitar los errores de seguridad más comunes.
Al tratar el tema de la seguridad, hacemos hincapié en la necesidad de proteger totalmente la máquina completa (no únicamente el servidor MySQL) contra todos los tipos de ataques posibles; intercepción pasiva de paquetes, alteración, reproducción de comandos (playback), y denegación de servicio. Aquí no tratamos todos los aspectos de disponibilidad y tolerancia a fallos.
Para todas las conexiones, consultas, y otras operaciones que los usuarios pueden intentar realizar, MySQL utiliza seguridad basada en Listas de Control de Acceso (ACLs). También hay algún soporte para conexiones cifradas mediante SSL entre clientes y servidores MySQL. Muchos de los conceptos que aquí se exponen no son específicos de MySQL; las mismas ideas generales se pueden aplicar a cualquier aplicación.
Al ejecutar MySQL, siga siempre que sea posible estas recomendaciones:
·         ¡No de nunca a nadie (excepto a la cuenta root de MySQL acceso a la tabla user en la base de datos mysql! Esto es crítico. La clave cifrada es la verdadera clave en MySQL.Cualquiera que sepa cual es la clave que hay en la tabla user y tenga acceso a la máquina host de la cuenta registrada puede acceder fácilmente como ese usuario.
·         Estudie el sistema de privilegios de acceso de MySQL. Las sentencias GRANT y REVOKEse utilizan para controlar el acceso a MySQL. No otorgue más privilegios de los necesarios. Nunca otorgue privilegios a un mismo usuario sin tener en cuenta el equipo desde el que se conecta.
Lista de comprobaciones:
o    Pruebe el comando mysql -u root. Si es capaz de conectar al servidor sin la necesidad de introducir una clave, tiene problemas. ¡Cualquiera puede conectar a su servidor MySQL como el usuario root de MySQL con privilegios totales! Revise las instrucciones de instalación de MySQL, prestando atención en concreto a la información sobre establecer una clave para el usuario root. Consulte Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”.
o    Utilice la sentencia SHOW GRANTS y compruebe quién tiene acceso a qué. Después utilice la sentencia REVOKE para denegar los privilegios que no son necesarios.
·         No almacene ninguna clave sin cifrar en su base de datos. Si alguien tuviera acceso a su ordenador, el intruso podría obtener la lista completa de claves y utilizarlas. En vez de eso, utilice MD5()SHA1(), o cualquier otra función de hashing de un sentido.
·         No elija claves que puedan aparecer en un diccionario. Existen programas especiales para romperlas. Incluso claves como ``xperro98'' son muy malas. Es mucho mejor ``oweei98'', que contiene la misma palabra ``perro'' pero escrita desplazándose una tecla a la izquierda en un teclado QWERTY convencional. Otro método es usar ``Mtupc'', que ha sido tomada de las primeras letras de cada palabra de la frase ``María tuvo un pequeño corderito.'' Así es fácil de recordar y escribir, pero difícil de adivinar para cualquiera que no la conozca.
·         Invierta en un firewall. Le protegerá de al menos el 50% de todos los tipos de vulnerabilidades de cualquier software. Ponga MySQL tras el firewall o en una zona desmilitarizada (DMZ).
Lista de comprobaciones:
o    Intente escanear sus puertos desde Internet utilizando una herramienta como nmap. MySQL utiliza el puerto 3306 por defecto. Este puerto no debería ser accesible desde lugares no confiables. Otra manera simple de probar si el puerte MySQL está abierto o no es intentar el siguiente comando desde alguna máquina remota, dondeserver_host es la máquina en la que su servidor MySQL se está ejecutando:
shell> telnet server_host 3306
Si consigue conectar y algunos caracteres extraños, el puerto está abierto, y debería cerrarlo en su firewall o router, a menos que tenga una buena razón para mantenerlo abierto. Si el comando telnet no consigue conectar o la conexión es rechazada, entonces el puerto se encuentra bloqueado, que es como queremos que esté.
·         No confíe en ningún dato enviado por los usuarios de sus aplicaciones. Pueden intentar engañar a su código introduciendo secuencias de caracteres especiales en formularios webs, URLs, o cualquier aplicación que haya desarrollado. Asegúrese de que su aplicación permance segura si un usuario introduce algo como ``; DROP DATABASE mysql;''. Este es un ejemplo algo extremo, pero los mayores agujeros de seguridad y pérdidas de datos pueden ocurrir como resultado de hackers utilizando técnicas similares, si no se está preparado para ellas.
Un error común es proteger únicamente valores de tipo cadena de caracteres. Recuerde comprobar los datos numéricos también. Si una aplicación genera una consulta como SELECT * FROM table WHERE ID=234 cuando un usuario introduce el valor 234, el usuario podría introducir el valor 234 OR 1=1 para provocar que la aplicación genere la consulta SELECT * FROM table WHERE ID=234 OR 1=1. Como resultado, el servidor extraerá todos los registros en la tabla. Esto, además de exponer cada registro, causa una carga excesiva en el servidor. La manera más simple de protegerse frente a este tipo de ataque es utilizar comillas simples alrededor de las constantes numéricas: SELECT * FROM table WHERE ID='234'. Si el usuario entrase información extra, todo sería parte de la cadena de caracteres. En un contexto numérico, MySQL automáticamente convierte esta cadena en un número, y elimina cualquier carácter no númerico del final que la cadena pueda contener.
A veces la gente piensa que si una base de datos contiene sólo datos de dominio público, no tiene por qué ser protegida. Esto es incorrecto. Aunque sea admitible mostrar cualquier registro de la base de datos, siempre se debería proteger contra ataques de tipo denegación de servicio (por ejemplo, aquellos que se basan en la técnica del párrafo precedente, que causan que el servidor malgaste recursos). Si no, el servidor podría quedar inservible para sus usuarios legítimos.
Lista de comprobaciones:
o    Intente introducir comillas simples y dobles (''' y '"') en todos sus formularios web. Si obtiene cualquier clase de error MySQL, investigue el problema sin demora.
o    Intente modificar las URLs dinámicas añadiendo las cadenas %22 ('"'), %23 ('#'), y%27 (''').
o    Intente modificar los tipos de datos en las URLs dinámicas de tipos numéricos a alfanuméricos, usando los caracteres mostrados en los ejemplos previos. Su aplicaicón debería ser segura contra estos y otros ataques similares.
o    Intente introducir letras, espacios, y símbolos especiales en vez de números en los campos numeicos. Su aplicación debería eliminarlos antes de pasarlos a MySQL, o en todo caso generar un error. ¡Pasar valores sin comprobar a MySQL es muy peligroso!
o    Compruebe el tamaño de los datos antes de pasárselos a MySQL.
o    Haga que su aplicación se conecte a la base de datos utilizando un nombre de usuario diferente del que utiliza para tareas administrativas. No dé a sus aplicaciones ningún acceso que no necesiten.
·         Muchas interfaces de programación de aplicaciones proveen alguna manera de preceder con caracteres de escape los caracteres especiales en sus datos. Usados adecuadamente, esto previene que los usuarios de las aplicaciones introduzcan valores que provoquen que la aplicación genere sentencias con efectos diferentes a los que usted pretendía:
o    API MySQL de C: Utilice la función mysql_real_escape_string().
o    MySQL++: Utilice los modificadores escape y quote para streams
o    PHP: Utilice la función mysql_escape_string(), que está basada en la función del mismo nombre de la API MySQL de C. (Con versiones anteriores a PHP 4.0.3, utilice addslashes() en cambio.) En PHP 5, puede utilizar la extensión mysqli, que soporta los protocolo de autentificación y clave de acceso mejorados de MySQL, así como las sentencias preparadas con placeholders.
o    DBI de Perl: Utilice el método quote() o utilice placeholders.
o    JDBC de Java: Utilice un objeto PreparedStatement y placeholders.
Otras interfaces de programación deberían tener capacidades similares.
·         No transmita datos sin cifrar por Internet. Esta información es accesible para cualquiera que tenga el tiempo y la habilidad para interceptarla y utilizarla para sus propios propósitos. En vez de eso, utilice un protocolo de cifrado como SSL o SSH. MySQL soporta conexiones SSL internas desde la versión 4.0.0. El redireccionamiento de puertos de SSH se puede utilizar para crear un tunel cifrado (y comprimido) para la comunicación.
·         Aprenda a utilizar las herramientas tcpdump y strings. En la mayoría de los casos, usted puede comprobar si los flujos de datos de MySQL están cifrados ejecutando un comando como el siguiente:
shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
(Esto funciona en Linux, y debería funcionar, con pequeñas modificaciones en otros sistemas.) Atención: Si no ve los datos en formato de texto, esto no siempre quiere decir que la información esté realmente cifrada. Si necesita un alto nivel de seguridad, debería consultar a un experto en la materia.

5.5.2. Hacer que MySQL sea seguro contra ataques

Cuando se conecta a un servidor MySQL, debería utilizar una clave. La clave no se transmite en texto llano a través de la conexión. El tratamiento de las claves durante la conexión de un cliente ha sido mejorado en MySQL 4.1.1 para ser muy seguro. Si todavía está utilizando claves del tipo anterior a 4.1.1, el algoritmo de cifrado no es tan potente como el nuevo algoritmo; con un poco de esfuerzo un atacante inteligente que pueda interceptar el tráfico entre el cliente y el servidor podría romper la clave. (Consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1” para una explicación sobre los diferentes métodos de tratamiento de claves.) Si la conexión entre el cliente y el servidor pasa a través de una red no segura, debería utilizar un tunel SSH para cifrar la comunicación.
Toda la demás información se transmite como texto, y puede ser leida por cualquiera que pueda observar la conexión. Si esto le preocupa, utilice el protocolo comprimido para hacer que el tráfico sea mucho más difícil de descifrar. Para hacer la conexión aún más segura, debería utilizar SSH para conseguir una conexión TCP/IP cifrada entre el servidor MySQL y el cliente MySQL. Puede encontrar un cliente SSH Open Source en http://www.openssh.org/, y un cliente comercial enhttp://www.ssh.com/.
En MySQL 5.0, puede utilizar también el soporte interno de OpenSSL. Consulte Sección 5.7.7, “Usar conexiones seguras”.
Para convertir un sistema MySQL en seguro, debería considerar seriamente las siguientes sugerencias:
·         Utilice claves para todos los usuarios MySQL. Un programa cliente no conoce necesariamente la identidad de la persona utilizándolo. Es común en las aplicaciones cliente/servidor que el usuario pueda especificar cualquier nombre de usuario al programa cliente. Por ejemplo, cualquiera puede utilizar el programa mysql para conectarse como cualquier otra persona, simplemente invocándolo de la siguiente manera: mysql -uotro_usuario nombre_bd cuando otro_usuario no tiene clave. Si todos los usuarios tienen una clave, conectarse utilizando la cuenta de otro usuario se vuelve mucho más difícil.
Para cambiar la clave de un usuario, utilice la sentencia SET PASSWORD. También es posible alterar la tabla user en la base de datos mysql directamente. Por ejemplo, para cambiar la clave de todas las cuentas MySQL que tienen por nombre de usuario root, haga lo siguiente:
shell> mysql -u root
mysql> UPDATE mysql.user SET
Password=PASSWORD('newpwd')
    -> WHERE User='root';
mysql> FLUSH PRIVILEGES;
·         Nunca ejecute el servidor MySQL con el usuario root de Unix. Esto es extremadamente peligroso porque cualquier usuario con el privilegio FILE es capaz de crar ficheros como root(por ejemplo, ~root/.bashrc). Para prevenir esto, mysqld rechaza ejecutarse como root a menos que se utilice explícitamente la opción --user=root.
En vez de eso, mysqld puede (y debe) ser ejecutado mediante un usuario normal sin privilegios. Puede crear una cuenta de Unix específica llamada mysql para hacelo todo aún más seguro. Utilice esta cuenta tan solo para administrar MySQL. Para ejecutar mysqldmediante un usuario de Unix diferente, añada la opción user que especifica el nombre de usuario al grupo [mysqld] del fichero de opciones /etc/my.cnf o al fichero de opcionesmy.cnf en el directorio de datos del servidor. Por ejemplo:
[mysqld]
user=mysql
Esto provoca que el servidor se inicie mediante el usuario designado, lo ejecute usted manualmente o mediante mysqld_safe o mysql.server. Para más detalles, consulteSección A.3.2, “Cómo ejecutar MySQL como usuario normal”.
Ejecutar mysqld como un usuario Unix diferente de root no significa que necesite cambiar el usuario root de la tabla user. Los usuarios de las cuentas MySQL no tienen nada que ver con los usuarios de las cuentas Unix.
·         No permita el uso de enlaces simbólicos a tablas. (Esto puede desactivarse con la opción--skip-symbolic-links.) Esto es especialmente importante si ejecuta mysqld comoroot, porque cualquiera que tenga acceso de escritura al directorio de datos del servidor ¡podría entonces borrar cualquier fichero en el sistema!. Consulte Sección 7.6.1.2, “Utilización de enlaces simbólicos para tablas en Unix”.
·         Asegúrese de que el único usuario Unix con permisos de lectura o escritura en los directorios de la base de datos es el usuario que ejecuta mysqld.
·         No otorgue los privilegios PROCESS o SUPER a usuarios no-administrativos. La salida del de mysqladmin processlist muestra el texto de cualquier sentencia que se esté ejecutando, así que cualquier usuario al que se permita ejecutar ese comando puede ser capaz de ver si otro usuario ejecuta una sentencia UPDATE user SET password=PASSWORD('not_secure').
mysqld reserva una conexión extra para usuarios que tengan el privlegio SUPER, así que un usuario root puede conectarse y comprobar la actividad del servidor aún cuando todas las conexiones normales estén en uso.
El privilegio SUPER puede utilizarse para cerrar conexiones de cliente, cambiar el funcionamiento del servidor modificando el valor de variables del sistema, y controlar servidores de replicación.
·         No otorgue el privilegio FILE a usuarios no-administrativos. Cualquier usuario que posea este privilegio puede escribir un archivo en cualquier de lugar del sistema de ficheros con los privilegios del demonio mysqld. Para hacer esto un poco más seguro, los archivos generados con SELECT ... INTO OUTFILE no sobreescriben archivos existentes, y pueden ser escritos por cualquiera.
El privilegio FILE puede también ser utilizado para leer cualquier archivos que sea legible por cualquiera o accesible para el usuario Unix que ejecuta el servidor. Con este privilegio, podría por ejemplo leer cualquier fichero e insertarlo en una tabla de la base de datos. Esto podría utilizarse, por ejemplo, utilizando LOAD DATA para cargar /etc/passwd en una tabla, que podría ser mostrada después con un SELECT.
·         Si no confía en sus DNS, podría utilizar números IP en vez de nombres en las tablas de permisos (tablas grant). En cualquier caso, debería ser muy cuidadoso en crear registros en las tablas de permiso utilizando nombres que contengan caracteres comodín.
·         Si quiere restringir el número de conexiones permitidas para una misma cuenta, puede hacerlo estableciando la variable max_user_connections de mysqld. La sentencia GRANTtambién soporta opciones de control de recursos para limitar la extensión de uso de servidor permitido a una cuenta. Consulte Sección 13.5.1.3, “Sintaxis de GRANT y REVOKE.fuentefuente

0 comentarios :

Publicar un comentario