X

Proteger aplicaciones Ruby on Rails de ataques SQL INJECTION

En el siguiente artículo se va a exponer los mecanismos de protección de seguridad de las aplicaciones web Ruby on Rails frente a los ataques de inyección SQL.

La seguridad de las aplicaciones webs depende del conocimiento y experiencia de los programadores, y es el resultado de la seguridad aplicada en cada una de las capas de la aplicación.

Las últimas estadísticas y estudios siguen indicando que aproximadamente el 75% de los ataques realizados tienen como víctimas a las propias aplicaciones webs, y esos mismos estudios indican que casi el 100% de los sitios auditados contenían algún tipo de vulnerabilidad en la capa de aplicación.

Uno de los más famosos y habituales ataques a la capa de aplicación se denomina SQL Injection, tal y como indica el TOP 10 de OWASP (The Open Web Application Security Project). Dicho ataque consiste en modificar los parámetros de entrada de un formulario para obtener al formar la sentencia SQL un resultado no esperado por la aplicación.

En el siguiente ejemplo se muestra código fuente vulnerable

Project.find(:all, :conditions => «name = ‘#{params[:name]}'»)

Si un atacante introduce en el parámetro ‘ OR 1=1’ la sentencia SQL resultante será:

SELECT * FROM projects WHERE name = » OR 1 –‘

Por lo que la sentencia devolverá todos los registros de la tabla Project, ya que la condición es siempre verdadera para todos los registros.

Otro ejemplo se código vulnerable permitiría a un atacante autenticarse en la aplicación sin tener conocimiento previo de ninguna credencial:

User.find(:first, «login = ‘#{params[:name]}’ AND password =

‘#{params[:password]}'»)

Si el atacante introduce ‘ OR ‘1’=’1 en el nombre, y ‘ OR ‘2’>’1 en la contraseña, la sentencia SQL resultante será:

SELECT * FROM users WHERE login = » OR ‘1’=’1′ AND password = » OR ‘2’>’1′

LIMIT 1

Por lo que se encontrará el primer registro de la tabla users y se permitirá el acceso con dicho usuario.

Ruby on Rails posee un filtro para caracteres SQL especiales. Utilizando Model.find(id) o Model.find_by_something(something) automáticamente aplicará la contramedida frente a ataques de inyección SQL, aunque en fragmentos de condiciones SQL  (:conditions => «…»), los métodos connection.execute() o Model.find_by_sql (),tiene que ser aplicado de forma manual.
En lugar de pasar una cadena a la opción de condiciones, se puede pasar una matriz para limpiar las cadenas de la siguiente forma:
Model.find (: en primer lugar,: Condiciones => [«? Login = Y = contraseña», entered_user_name, entered_password]). La primera parte de la matriz es un fragmento de SQL con signos de interrogación.

También se puede pasar un hash para el mismo resultado:

Model.find (: first,: Condiciones => {: login => entered_user_name,: password =>entered_password}).

En otros casos se puede emplear sanitize_sql(condition, table_name = self.table_name).

Áudea Seguridad de la Información
Antonio Martínez
Departamento Seguridad TICs
www.audea.com

Artículos Relacionados