miércoles, 18 de julio de 2012

Distancia de edición

adminitrador: Saludos User123
user123: Saludos
adminitrador: disculpe por las molestias, pero lamento informaros que nuestra base de datos ha sido comprometida y por lo que parece, por una persona de nuestro equipo.
user123: Lo lamento, pero y  ¿por qué me estás diciendo eso? no tengo nada que ver con lo que ha sucedido.
adminitrador: estamos llevando una investigación a fondo, y como se podrá . . .

¡Espera un momento! ¿Quién diablos es ese? ¡administrador sin s!

Bueno, sin duda ese era alguien un poco más astuto de la cuenta, y estoy seguro de que hubo personas que no pudieron percibir ese pequeño detalle mientras leían la parte de arriba.

El robo de identidad es algo muy común en la red y muchas veces es muy fácil de llevar a cabo, veamos como podemos proteger a los usuarios y nuestra web, en lo posible, de este tipo de cosas utilizando la distancia de edición de Levenshtein, o simplemente distancia de Levenshtein:

Antes de comenzar, necesitarás la siguiente gema:
gem install levenshtein
Continuando, según el ejemplo del timador de arriba, para nuestros fines, consideraremos insegura cualquier palabra que necesita dos o menos cambios para convertirse en otra.

Primero probemos un poco con irb:
irb(main):001:0> require 'levenshtein'
=> true
irb(main):002:0> Levenshtein.distance("administrador", "adminitrador")
=> 1
irb(main):003:0> Levenshtein.distance("webmaster", "wepmaster")
=> 1
irb(main):004:0> Levenshtein.distance("administrador", "administradores")
=> 2
irb(main):005:0>
Viendo los resultados, podríamos concluir que si tenemos un usuario de nombre webmaster, sería inseguro aceptar otro usuario de nombre wepmaster, de la misma manera para: administrador y adminitrador; administrador y administradores.

Preparemos ahora otro ejemplo, pero esta vez uno que lea una lista de usuarios y de ellas nos diga si es seguro aceptar el usuario o no.
require 'levenshtein'

RULE= 2

def safe_name?(pool, username, rule=RULE)
     not pool.any? do|name|
          Levenshtein.distance(name, username) <= rule
     end
end

if ARGV.empty?
     $stderr.puts "Uso: ruby #{$0} <usuario>"
     exit
end

# pool = IO.read('lista_usuarios.txt').scan(/\w+/)

pool = %w{ administrador abogado policia admin webmaster
           paypal google yahoo amazon dios jesus gandhi}

if safe_name?(pool, ARGV[0].downcase)
     puts "El nombre de usuario `#{ARGV[0]}' es seguro."
else
     puts "`#{ARGV[0]}' no es un nombre de usuario seguro."
end

~ $ ruby edit_distance.rb googel
`googel' no es un nombre de usuario seguro.

$ ruby edit_distance.rb jesu
`jesu' no es un nombre de usuario seguro.

$ ruby edit_distance.rb gandi 
`gandi' no es un nombre de usuario seguro.
                                        
~ $ ruby edit_distance.rb abogados
`abogados' no es un nombre de usuario seguro.

Conclusión

Últimamente los entornos de trabajo modernos (frameworks) integran mecanismo como este, de modo que la responsabilidad de comprobar este tipo de cosas recae en el sistema y no en el programador, pero nunca está de más estar alerta y consciente de los lugares de entrada y la forma de tapar esos huecos.

Ya con esto haremos que nuestros usuarios estén un metro más lejos de las garras de personas malintencionadas y brindaremos una capa más de seguridad a nuestra aplicación. Para aquellos que utilicen PHP en vez de Ruby, buenas noticias, PHP incluye en su librería estándard la función levenshtein() .

Enlaces Útiles

No hay comentarios:

Publicar un comentario