Contraseñas seguras para desarrolladores

Vamos a hablar un poco sobre como mantener las contraseñas seguras en nuestras aplicaciones. Empezaremos con una explicación básica de encripcion de contraseñas mediante funciones hash y luego seguiremos con el uso de sal (del ingles salt, donde seguramente encontraran mas información) tanto estática como dinámica, terminaremos con alguna locura de mi ocurrencia.

password

Contraseñas hasheadas

Una función hash (por ejemplo md5 o sha) es una que ante una entrada, que en nuestro caso va a ser una contraseña, genera un digesto de longitud fija. Por ejemplo md5 ante una entrada de cualquier longitud genera una cadena de 128 bits que es equivalente a 16 bytes. Esta función no tiene inversa, por lo que desencriptar una contraseña no es fácil.

Así por ejemplo si la contraseña elegida es “contraseña” la función md5 nos devuelve: 4c882dcb24bcb1bc225391a602feca7c

Y si nuestra contraseña es “123” nos devuelve: 202cb962ac59075b964b07152d234b70

Usando esta función podemos guardar en nuestra base de datos los valores hasheados de las contraseñas. Cuando un usuario intenta loguearse le aplicamos la función hash a lo que ingreso como password y luego comparamos con lo que tenemos guardado en la base de datos.

Si nuestra base de datos se ve comprometida estaríamos poniéndole una traba a los que quieren robar las contraseñas. El problema radica en que alguien con el suficiente tiempo y con un diccionario de contraseñas puede generar una tabla con los resultados de la función de hash, generalmente se conoce esto como una tabla rainbow.

De esta forma si se dispone de una tabla rainbow podemos comparar los valores hasheados para obtener el valor de la contraseña (mas adelante veremos que esto no es completamente cierto por eso de la colisiones de las funciones hash)…

saltHasheado y salado de contraseñas (salt estática)

El problema que nos generan las tablas rainbow puede paliarse con el uso de una cadena de caracteres que se le agregue a cada contraseña antes de aplicarle la función de hash. Esa cadena de caracteres es lo que se conoce como la sal (o el salt). Veamos un ejemplo:

Nuestra contraseña es “contraseña” como la que vimos anteriormente, ahora vamos a agregar nuestra sal digamos que es algo tan básico como (123). Si hacemos md5(123+contraseña) el resultado es: 46eb9acec1a2dfd3217b786122697d69. El valor obtenido de la función de hash puede estar presente en una tabla rainbow pero nuestro atacante no debería poder saber que parte corresponde a la contraseña y que parte a la sal. Sobre todo si tenemos en cuenta las colosiones que puede generar esta funcion.

Colisiones en funciones de hash

Se llama colisiones a diferentes entradas que generan el mismo resultado de la función de hash. Si solo usamos una funcion de hash no necesitamos obtener la contraseña verdadera sino que con obtener una cadena de caracteres que al aplicarle la función nos devuelva el mismo resultado nos alcanza para loguearnos.

Si nuestro atacante obtiene un valor que pueda utilizarle tiene que poder separar la parte de la sal y si es por una colisión esto se vuelve imposible.

Contraseñas hasheadas con salt (salado dinamico)

El problema del punto anterior es que si el atacante obtiene el valor del salt puede generar una tabla rainbow especifica para atacar nuestra aplicación. Teniendo un diccionario lo suficientemente grande al cual se le concatena la sal a cada entrada se puede obtener la correlación de las contraseñas originales con el valor del hash resultante.

Para evitar esto podemos utilizar valor de hash dinámicos para cada usuario. Podemos guardar (en la misma base de datos o en otro lado si se quiere mayor seguridad) un valor de salt diferente para cada usuario, usando una función que devuelva una cadena random que generamos en el momento del registro.

Usando esta técnica al momento de loguearse un usuario tomamos la contraseña que ingreso, consultamos la base de dato y calculamos el valor del hash resultante de concatenar la contraseña ingresada + la cadena guardada.

Si guardamos la sal en la misma base de datos podemos pensar que nuestras contraseñas serán casi tan vulnerables como en el primer ejemplo, la realidad es que el atacante debería generar una tabla rainbow para cada usuario si quiere obtener todas las contraseñas. Esto es, por ahora, computacionalmente inviable para el común de los mortales, pero alguien con el suficiente interés, y con el poder de calculo suficiente, podría vulnerar la mayoría de nuestras contraseñas.

Agregando pimienta

pimientaPara asegurar mas nuestra contraseña podemos utilizar un poco de ingenio. Por ejemplo combinar mas de 1 salt. Podemos tener un salt dinámico para cada usuario y uno estático que no se guarde en la base de datos. También podemos utilizar valores dinámicos que no se identifiquen como parte de la contraseña.

Por ejemplo podemos utilizar como entrada de nuestra función de hash: un salt estático guardo como variable de nuestra aplicación (no en la base de datos) + contraseña del usuario + salt dinámico + id de usuario. Así nuestra aplicación tendría una capa extra de protección presente únicamente en la lógica.

Incluso podemos aplicar la función hash recursivamente para agregar todavía mas seguridad, por ejemplo:

Allí estaríamos hasheando una contraseña hasheada agregando un nivel de complejidad extra. Incluso podríamos poner esto dentro de un “for” para aplicarlo la cantidad de veces que queramos haciendo prácticamente imposible que un atacante pueda obtener todas las contraseñas que tenemos alojadas en el sitio.

Evitar ataques de fuerza bruta

Todo muy lindo ¿no? pero también tenemos que asegurar cosas mas básicas, por ejemplo debemos evitar los ataques de fuerza de bruta. Si tenemos todo lo anterior pero le permitimos al atacante probar miles de contraseñas sin ningún tipo de control nuestra aplicación seguiría siendo insegura. Para ello podemos aplicar limitaciones como el clásico ha ingresado 5 veces erróneamente la contraseña debe esperar 15 minutos antes de volver a intentarlo.

Y… ¿Ustedes como aseguran sus contraseñas?

 

A dieta

Tengo casi 30 años soy gordo y fumo en el preocupacional que me hice hace poco la balanza acusó 135 kilos. Creo que es hora de hacerse cargo y tomar cartas en el asunto. Por eso mismo estoy comenzando la dieta. Casi toda mi vida hice dieta. Los últimos 20 años fueron un sin fin de bajadas y subidas de peso. Aunque los últimos fueron sobre todo subidas.
Ojo no tengo problemas con ser gordo, estéticamente hablando, pero estoy comenzando a notar como me afecta la  salud. Dolores de espalda, contracturas, agitamiento… Son cosas que le achaco a la gordura.
Mi meta es bajar 40 kilos en un año. No quiero, y creó que no podría lograrlo, bajar mucho más que eso. Con estar en las dos cifras ya estaría muy contento, hace muchos años que no estoy en menos de 100 kilos.
El cambio de trabajo no me va a permitir ejercitarme mucho. No por el trabajo en si, lo que jode es el viaje, dos horas de ida y dos horas de vuelta. Para los primeros kilos no va a significar un gran problema: con solo cambiar la alimentación creo que puedo bajar unos 10 o 15 kilos sin problema. Ya veré como hago cuando necesite gimnasia para seguir bajando.
En fin este año trae muchas cosas nuevas para mi… Espero poder lograr todo lo que me propuse

Consegui trabajo

Hace un mes y medio festejaba que me habia recibido… hace un mes publicaba que estaba buscando trabajo. Y puedo decir que ya lo consegui. El puesto que quiero, en la empresa que quiero, con los jefes que quiero. Mejor no me podria haber salido. En marzo empiezo.

No me quejo de mi actual trabajo. Fueron casi 8 años, me dio de comer, me permitio recibirme y colaboro en gran media con mi desarrollo como persona. Pero es una etapa que considero terminada. Conoci mucha gente interesante, algunos incluso puedo considerarlos amigos, pero es hora de seguir mi camino.

Me espera un mundo completamente nuevo, estoy contento con el cambio, algo asustado tambien, no es lo mismo trabajar para el estado que trabajar para una empresa privada. Y eso que no soy el tipico empleado publico.

Hay mucha gente que deposito su confianza en mi, el primero de todos el que me dio su recomendacion para que entre a trabajar. No tengo pensado fallarle a nadie, pienso dar el 100% como lo hago siempre, como lo hago en todos lados, pero es una responsabilidad enorme.

En fin… ya tengo nuevo trabajo y me estoy despidiendo del actual…

Usando ControllerAs en AngularJS

Estaba leyendo a John Papa, particularmente su guia de estilo para AngularJS. Según dicen algunos seguir esta guía hará que el paso a Angular 2.0 no sea tan difícil. Después de leerlo completamente ademas de eso considero que seguir esta guía nos devuelve un código mucho mas entendible. Uno de los puntos que mas me gusta es el de usar Controller As para evitar el uso de $scope. Así que agarre el ejemplo de upload de imágenes en angular y me puse manos a la obra para modificar el controlador.

Lo primero fue definir el controllerAs en el routeProvider y luego definir la función del controlador, no dejarla como una funciona anónima. Para ello solo debíamos hacer algunos cambios a la forma en que llamábamos al controlador, aproveche y cambie también la forma en que se hace la inyección de dependencias siguiendo lo que se recomienda John, de esta forma me quedo algo asi:

La definición de la ruta:

Notese el controllerAs… con esto y con algunos cambios en el controlador vamos a acceder a las variables mediante {{vista.loEsteDefinido}} quedando, creo yo bastante bien. Ademas nos ayuda a evitar colisiones cuando se superponen controladores en una vista.

En donde definí el controlador solo tengo lo siguiente:

Básicamente le estoy diciendo que el controlador VistaCtrl sera la funcion VistaCtrl. Ahora solo nos queda definir la función y hacer la inyección de dependencias:

La primer linea es la inyección y la segunda la definición de la función, como seguramente ya notaron. Entonces en todos los lugares en donde yo definia $scope.variable lo cambie por vm.variable (vm es por viewModel)…  Por ejemplo la función que envía la imagen quedo definida así:

Por ultimo en la vista ya no se accede con el nombre definido con $scope… ahora para acceder a la función o a cualquier otra variable definida dentro del controller utilizo vm.variable…

El uso de vm=this; es interesante, ya que se utiliza para evitar colisiones cuando definimos funciones dentro del controller lo que puede hacer que se pise el this…

Pueden ver el código en el repositorio de github… Allí voy a seguir subiendo algunas cosas según valla aprendiendo y teniendo tiempo de aplicar los cambios.

¿Que sigue?

Bueno… separar cada cosa en su propio archivo, no me terminaba de gustar la forma en que armaba todo angular seed y luego de leer la guia creo que me inclino mas por un archivo para cada cosa.

Modificar la directiva para que siga la misma convención de definir la función correctamente. Y hacer lo mismo con los servicios y factorys, que, de hecho, no se utilizaron la primer versión del upload de imágenes, pero que pretendo usarlas para dejar los controllers mas claros.

Upload de imagenes o archivos con AngularJS

Uno de los últimos proyectos en los que estuve involucrado fue una aplicación MEAN (MongoDB, Express, AngularJS y NodeJS). Funcionaba bastante bien. Pero nos encontramos con el problema de que debíamos subir una imagen… AngularJS no es muy amigo de los post Multipart ni de subir archivos. Ya sabemos que intenta serializar todo generar un json.

La solución que se encontró en un principio fue hacer un POST normal, de esos de toda la vida, no usar Angular para realizarlo, funcionaba, pero no era del todo de mi agrado, al final habíamos hecho una aplicación REST y fallábamos en una simple subida de archivos.

Después de mucho navegar, y con ayuda de estos posts pude entender en que nos estábamos equivocando y que era lo que se debía hacer para poder subir archivos con AngularJS… Veamos en detalle.

En primer lugar a un input tipo file si le asignamos un ng-model angular no va a detectar el cambio y por lo tanto nuestro ng-model siempre queda vacio (o por lo menos eso es lo que me pareció a mi); no vamos a poder hacer el POST de la imagen o el archivo que estamos intentando subir. Para hacerlo la mejor solución que encontré fue la de usar una directiva (benditas directivas, solo debemos aprender a utilizarlas para aumentar exponencialmente nuestra productividad con Angular). La directiva dice:

Allí básicamente le estamos diciendo a Angular que se fije en los elementos con “atributo” file-model y que ante un cambio le setee el archivo como atributo de modelo con el primer archivo que se selecciono (Porque interpreta que tenemos un array de archivos).

De esta forma mi formulario para subida de imágenes quedo así:

No tiene ninguna ciencia ¿no? ahora ya podemos asociar un archivo a un modelo para luego trabajar con angularjs.

El siguiente problema con el que me encontré fue con el subir el archivo propiamente dicho al servidor. Como dije antes el framework intenta armar un json con cualquier cosa que le pasemos, por lo tanto debemos hacer una transformación del Request para que no intente serializar nuestra imagen. A su vez para hacer el post con $http.post necesitamos los datos de un formulario, para ello usamos FormData…. El código que me quedo es así:

Tiene algunas cosas de mas, ya lo se, y algunas de menos también, pero la funcionalidad básica es esa. Creamos un nuevo FormData y hacemos el $http.post pasandole la url a la que le vamos a pegar y los datos del formulario luego hacemos el  “transformRequest: angular.identity” que básicamente le dice a AngularJS que deje los datos tal cual se los estamos pasando. Lo demás es la gestión después de haber intentado subir la imagen al servidor. Incluso tenemos una pequeña gestión de errores (que ahora no hace nada).

Pueden ver el código, que seguramente voy a retocar un poco, ya que ahora es solo una prueba de concepto y no tienen ningún tipo de seguridad ni manejo de errores, en github: https://github.com/Ferticidio/UploadAngular . Acepto ideas, comentarios y criticas que nos lleven a mejorar el código, creo que mas de uno se habrá encontrado con el mismo problema que yo…