viernes, julio 10, 2009

Seguridad en bases de datos... otra cosa mas de que preocuparse

He estado desconectado un poco del blog por motivos de trabajo, 3 cursos casi seguidos de Advantage Database Server, junto con un proyecto de esta misma base de datos para un gobierno estatal de México me han tenido alejado de OP por algunas semanas.

Esta semana con la entrega del proyecto a la dirección de informática del gobierno del estado, tuvimos una serie de reuniones con el personal de sistemas, y el comentario de esta semana surge precisamente a raíz de una de esas reuniones donde se nos cuestionaba sobre la seguridad implementada en la instalación de ADS que realizamos.

Como en toda buena entidad gubernamental, y en general en todas las empresas, la seguridad de la información es un factor que tenemos que cuidar cuando desarrollamos programas, en algunos países la protección de datos es incluso una ley, como en el caso de España, donde existe una Ley Orgánica de Protección de Datos, y comentando con la gente de informática nos decían que ellos habían dejado de usar bases de datos Open Source (MySQL, FireBird, Postgre SQL y otras) precisamente por los riesgos de seguridad que ello conlleva.

No me había yo puesto a pensar en eso..... sabemos que un software Open Source en un principio es confiable, es estable, se puede usar libremente sin tener que pagar por su uso, en general son productos de calidad excelente, no traen código "malicioso" dentro como spyware o troyanos porque el código fuente está disponible para que todo el mundo con los conocimientos adecuados vea lo que hay dentro.

Si no confías en un binario pre-construido de un producto Open Source que descargaste de internet, puedes descargar el código fuente y construir tu propio EXE, de hecho, muchos programadores de (x)Harbour lo hacen, se descargan el código fuente del SVS o del CVS y se construyen su compilador fresquesito a partir del código fuente, el código fuente de (x)Harbour tiene incluso archivos .BAT para facilitarte el construirte el compilador o las contribuciones.

¿ Que tan seguro a nivel información es usar no solo una base de datos Open Source, sino cualquier producto Open Source en general ?.

En el caso de los usuarios finales de nuestros desarrollos, sabemos que serán muchos mas que las personas que intervinieron en hacer el programa, y su principal interés es resolver sus problemas, realmente no creo que algún usuario final esté buscando "romper" nuestro programa, sencillamente porque no les interesa o no tienen los conocimientos técnicos adecuados para hacerlo, sin embargo, hay gente para todo y como siempre he dicho: Si hay algo peor que un usuario, es un usuario con iniciativa.

A nivel programación y programadores, todos estamos interesados en saber "como se hacen las cosas", y los códigos fuentes de los programas son usualmente excelentes fuentes de conocimiento para aprender un poco más, el código Open Source aporta conocimientos invaluables a los programadores porque no oculta nada del funcionamiento de un producto, TODO está allí y nos permite saber como se hace tal o cual cosa o bien saber como se soluciona tal o cual problema.

Pero no siempre la gente que revisa los códigos fuentes lo hace con buenas intenciones, si bien como programadores de (x)Harbour por ejemplo, difícilmente nos meteremos a las tripas del compilador para ver como funciona el DBUseArea() (tenemos otros problemas que resolver y no tenemos el tiempo de hacerlo o bien los conocimiento en "C" para interpretar el código) sí hay gente que está dispuesta a hacerlo, y lo hace, muchas veces con la nada sana intención de encontrar vulnerabilidades o de crear herramientas que puedan aprovechar para "atacar" al programa o para obtener la información que dichos programas custodian, como es el caso las bases de datos.

En esto de las vulnerabilidades no se salva nadie, ni los programas "propietarios" (los que no son Open Source), baste como ejemplo el Internet Explorer de Microsoft, ¿ cuantos "parches" de seguridad tienes instalados y que dice su descripción?: "parche que corrije la vulnerabilidad tal o cual", solo que mientras en un programa propietario la vulnerabilidad puede ser difícil de encontrar partiendo del EXE final, en un producto Open Source los hackers tienen la vida resuelta, tienen a mano el código fuente, les entregamos las armas en bandeja. Si planeas un asalto a la bóveda de un banco, es mas fácil hacerlo con los planos del lugar que mirando simplemente el edificio desde afuera.

En las comunidades Open Source, cuando se descubre una vulnerabilidad, esta suele corregirse muy rápido (después de todo tienen el código fuente), pero mientras la gente que usa el programa actualiza la versión, la vulnerabilidad sigue presente ahí, poniendo en riesgo a los usuarios del producto que presenta ese fallo.

Por otro lado teniendo el código fuente a la mano, ¿ quien te garantiza la seguridad de tus datos ?, por ejemplo en el caso de PostgreSQL, Firebird o el mismo MySQL, quien me garantiza que no haya un hacker por ahí que tenga una versión del manejador de base de datos que pueda saltarse el proceso de autenticación del usuario y que pueda leer los datos de cualquier servidor, después de todo, la información para hacerlo es pública, disponible para todos los usuarios, y todos los servidores utilizan el mismo código fuente.

Explorando un poco mas el tema, (basta con poner en Google "hacking MySQL", por ejemplo) y te salen un montón de páginas web donde lo mismo te dicen como conectar con el servidor para leer datos como usuario "root" sin necesidad de tener password, así como herramientas y programas de hackeo, códigos fuentes para listar todas las bases de datos de un servidor, etc..

Una vulnerabilidad que me llamo mucho la atención fue la llamada "SQL injection" que consiste en utilizar los datos capturados en un programa "cliente" para introducir código SQL malicioso al servidor MySQL o bien para dañar las tablas, veamos un ejemplo:

Tenemos un programa hecho por ejemplo en (x)Harbour que pide el usuario y password para permitirnos acceder a un sistema que almacena los datos en MySQL (donde he visto yo eso, donde, donde), aparece nuestra ventana, pedimos los datos y luego ejecutamos un query para verificar que tanto el usuario como el password existan y sean válidos, por ejemplo:

Select count(*) from usuarios where nombre = '[nombre]' and password = '[password]'

Si el [nombe] y [password] son correctos, entonces COUNT(*) devolverá "1", si alguna de las 2 condiciones falla, ya sea que no exista el usuario, o que el password no sea el correcto, COUNT(*) devuelve "0" por lo tanto el usuario no tiene acceso al sistema, ya que si tecleamos por ejemplo: Usuario: Pepe password: pepito entonces nuestra sentencia SQL quedaria como:

Select count(*) from usuarios where nombre = 'Pepe' and password = 'pepito'

Si existe el usuario Pepe con el password pepito, podemos entrar al sistema, ahora vamos a hackear esta sentencia usando SQL injection, para que no me valide el password, para ello, el nombre del usuario que usaremos será: Pepe'# (sí, con el ' y el signo de # en el nombre)

La sentencia SQL entonces quedaría como:

Select count(*) from usuarios where nombre = 'Pepe'# ' and password = ''

El signo de # en MySQL indica comentario, con lo cual, a partir del #, el resto de la línea en esta sentencia es tomada como un comentario y se ignora, así pues, NO HAY VALIDACION DEL PASSWORD !!!! y si hay un nombre de usuario Pepe, entonces entraremos al sistema sin mucho problema porque Count(*) devolverá "1".

¿ Quieres toda la información de la tabla usuarios, obtenida desde el programa ?, usemos nuevamente al usuario Pepe para lograr nuestros malevolos planes, ahora Pepe se llama: Pepe'; Select * from usuarios INTO OUTFILE 'c:\share\micarpeta\usuarios.txt' #

La sentencia SQL que se ejecuta quedaría como:

Select count(*) from usuarios where nombre = 'Pepe'; Select * from usuarios INTO OUTFILE 'c:\share\micarpeta\usuarios.txt' # ' and password = ''

Con esto generaremos un archivo llamado usuarios.txt en el servidor, y si tengo acceso a la carpeta "micarpeta" en el servidor, pues nada, la lista de los usuarios del sistema entregada a domicilio.

Vamos a ser mas dramáticos, y vamos a usar la misma técnica ahora para borrar la tabla de usuarios ( después de todo, ¿ que sería de la vida sin un poco de caos alrededor ?), ahora el usuario será: Pepe'; Drop usuarios #

Y la sentencia SQL:

Select count(*) from usuarios where nombre = 'Pepe'; Drop usuarios # ' and password = ''

Y con esto ya nos cargó el payaso, porque el select se ejecuta primero, y después el DROP, y con eso le decimos adiós a la tabla de usuarios.

Obviamente este es un ejemplo demasiado simplista, para empezar el nombre del usuario debería estar limitado en el número de caracteres a teclear, pero sirve para ilustrar algo que en realidad puede suceder si somos poco dedicados en esa parte del diseño de sistemas llamado "análisis de la base de datos".

Esto se podría evitar si en vez de tener las instrucciones SQL metidas dentro del programa fuente tuvieramos procesos almacenados, o bien si ponemos especial cuidado en la creación y configuración de los usuarios de la base de datos, indicando qué usuario tiene acceso a qué tablas y con que privilegios (update, delete, drop, etc), pero siendo francos.... ¿ quien hace eso ?, ya no digas en MySQL, en CUALQUIER base de datos.

Este es solo un ejemplo de una sola vulnerabilidad (la cual es conocida y está documentada), buscando en internet una tarde puedes encontrar otros muchos ejemplos mas interesantes y no solo para MySQL, sino para casi cualquier producto popular Open Source.

Y ojo, no se me malinterprete, no solo los programas Open Source están afectados, como ya mencioné los programas propietarios también tienen dichas vulnerabilidades, y también hay programas externos que permiten extraer los datos controlados por ellos, pero como también mencioné, es mucho mas fácil saber como hackear un producto, cuando tienes el código fuente a la mano.

9 comentarios:

Juan Hernandez dijo...

El tema de la seguridad en base de datos es bastante interesante y muy delicado. Trae de cabeza por supuesto a muchas personas. En mi opinion, no existe producto que sea 100% seguro. Siempre habra forma de hackerlos y mas cuando desde la misma fuente se "fuga" informacion sobre su arquitectura o desarrollo. Es como la pirateria de musica... Cómo nos explicamos que se encuentren a la venta los "clones" antes de que salga el producto al mercado?... - Una manera de reforzar esta seguridad es hacer que desde la aplicacion se "manipulen" los datos guardandolos e forma "encriptada". Claro esta que la misma aplicacion debera "desencriptarlos" al leerlos del archivo para poder interpretarlos nuevamente. El punto debil de esta idea es que no nos salvamos de un borrado total si logran ingresar a los servidores. Solo conseguimos proteger un poco mas del robo de informacion no asi su destrucion. Apoyemonos tambien con buenos mecanismos de respaldo. Saludos!

www.capelblog.com dijo...

Hola René,

Las vulnerabilidades de un software no dependen de si es software libre o cerrado. Dependen del número de usuarios que lo utilicen. A más usuarios, más hackers interesados en reventar la seguridad de ese producto. El ejemplo claro lo has puesto tu, el Internet Explorer de MS es uno de los que más vulnerabilidades le han detectado... y no es libre... nadie más que MS tiene el código... y ahí está... cada mes hay una lista de vulnerabilidades 'corregidas'. Y MySql tiene muchas vulnerabilidades por que es una de las bases de datos más utilizadas de forma 'on-line'. Las vulnerabilidades en bases de datos 'off-line' son más difíciles de detectar al tener menos 'objetivos' disponibles donde atacar.

Y luego hablas de la injección de código como si fuera algo intrínseco a MySql. La injección de código aparece donde el programador no ha puesto especial énfasis en la protección de las sentencias que se crean a partir de 'código externo'. Yo he sufrido ese problema... y lo corregí sin tener que actualizar el sistema de base de datos...

Y ya puestos a dudar... ¿quien te asegura que el software enlatado no tenga puertas traseras que tu desconeces y que se pueden abrir si que tu te enteres?

Saludos,
José Luis Capel

Rene Flores dijo...

Juan:

Algunos gestores de base de datos, como SQLServer, Advantage u Oracle te permiten guardar los datos encriptados usando llaves que solo el programador de la base de datos conoce, el proceso de desencriptamietno es realizado por el servidor de datos, de tal forma que los datos están guardados de forma encriptada y cuando se envian al cliente, el servidor de datos los desencripta y los envia, lo mismo cuando se guardan datos, el servidor los recibe desencriptados, los encripta y los guarda encriptados.


Un buen sistema gestor de base de datos debe de obtener automáticamente sus respaldos, así mismo debe poder replicar los datos en otros servidores, sin embargo casi nadie se toma la molestia de implementar los mecanismos de seguridad y mucho menos de implementar seguridad a nivel tabla, o registro.

Hace unos meses en el foro de Xailer se generó un comentario sobre respaldo de tablas de MySQL, y sucede que la forma en que MySQL hace los respaldos a través de MySQLDump, deja a la vista TODA la información de la base de datos, ya que el proceso de respaldo genera un script SQL gigantesco, en texto, con toda la informacion de la estructura de las tablas y lo que es peor, los datos almacenados de modo visible, al final Jose Gimenez hizo un programa respaldar los datos de MySQL usando tablas de SQLite.

Lo importante desde mi punto de vista es no ser descuidados en el tema de la protección de datos, si tenemos las herramientas para hacer nuestros datos seguros, merece la pena invertir el tiempo en tener datos seguros.

Rene Flores dijo...

José Luis:

No se te olvide también que el código fuente de MySQL anda por ahí volando por internet y eso aumenta su vulnerabilidad.

En cuanto al SQL injection, mencioné que era un ejemplo simplista, y que tendrían que pasar muchas cosas (léase descuidos del programador) para dejar abiertas las puertas a la inyección de código malicioso en los programas, de hecho el SQL Injection existe aún en las versiones 5.x de MySQL, es mas, esto es tan conocido que hasta es tema de cachondeo en tiras cómicas.

En cuanto a los software enlatado, es probable que esos programas no solo tengan una puerta trasera, sino que incluso estén haciendo alguna otra cosa mas de las que dicen que en realidad hacen, entiéndase troyanos, spyware, gusanos, etc. esa es la ventaja y tambien la desventaja del Open Source, que tu puedes ver que es en realidad lo que tiene dentro e incluso te puedes construir tu tu propio EXE, pero el echo de exista el codigo fuente disponible para que todo el mundo le meta mano, si es para mejorar, que bueno .... ¿ pero si no ????

bronius dijo...

Rene , todo esto que comentas es cierto, pero tambien depende mucho
de que el hacker tenga acceso al equipo en cuestion , yo creo no solo hay que velar por la seguridad de una base de datos sino de acceso al equipo.

En mi caso tengo un servidor en internet , que no niego que alguna vez sufri algun problema , pero teniendo cuidado con los programas que instalas y con la posibilidad de que otros logren acceso remoto a tu equipo, la seguridad se puede tener en un nivel bastante alto.

Firewall, Iptables , logs y demas ayudan a matener tu server en buenas condiciones , primordialmente denegndo acceso en los protocolos debidos a toda IP que no sea la que tiene que acceder por ejemplo.

En conclusion para lo que comentas sea posible deberian haber violado un monton de medidas de seguridad
previas.

Saludos

Bruno

Lautaro Moreira Armijo dijo...

Dentro de mis escasos conocimientos, el sql injection es un peligro "EN TODOS LOS SERVIDORES DE DATOS QUE USEN SQL", si en TODOS, y la unica solucion real es que se tenga extremo cuidado en la programacion, y los permisos, ademas de la obvia restriccion de acceso a los archivos fisicos, sean estos un servidor y otro ( respaldos, etc. )

Sobre el guardar los datos encryptados, creo que todos los motores de datos que se respetan ( abiertos y de pago ) incorporan herramientas, funciones, etc. para hacer esto, lo que pasa es que nosotros los programadores muchas veces desconocemos estas facilidades y al no estar demasiado visibles damos por hecho que no estan y volvemos a lo que conocemos, que por ser conocido no es mejor, sino mas facil de usar.

Atte.,

Lautaro Moreira

Lautaro Moreira Armijo dijo...

Ups, envie el post sin terminarlo, me faltaba decir advantage tambien es vulnerable al sql injection si se programa sin los necesarios resguardos, sino ver el comentario de este "Advantage Evanlist" en http://blog.advantageevangelist.com/2008/05/avoiding-sql-injection-attacks.html

Atentamente,

Lautaro Moreira

consumer2k8 dijo...

Creo que no esta de mas insistir en que el comentario acerca de sql injection en Mysql, ademas de simplista, es tendencioso. Ya alguien menciono que TODAS las bases de datos SQL son vulnerables a ese tipo de ataque, no es una cuestion de esta o aquella base de datos, es algo intrinseco al mecanismo sql y la unica solucion es filtrar los inputs de los usuarios. La base de datos que tan livianamente ha criticado el autor, permite replicacion en linea a traves de comunicaciones encriptadas por SSL, permite tambien storage encryption, no trivialmente, pero no conozco cuan trivial es el backup o encriptacion del Advantage ya que hace mas de 10 años que no lo uso.
Mysqldump no es un comando de 'respaldo', es un comando de 'volcado', y mal encaminado esta aquel que pretenda usarlo con fines de backup.

Grupo dijo...

entonces la pregunta es ?? Como usar parametros en Xailer para ejecutar procedimientos almacenados !!!!