Inyección SQL

From OWASP
Revision as of 00:10, 4 December 2012 by Galoget J. Latorre Ch. (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
This is an Attack. To view all attacks, please see the Attack Category page.



Visión General

Un ataque por inyección SQL consiste en la inserción o “inyección” de una consulta SQL por medio de los datos de entrada desde el cliente hacia la aplicación. Un ataque por inyección SQL exitoso puede leer información sensible desde la base de datos, modificar la información (Insert/ Update/ Delete), ejecutar operaciones de administración sobre la base de datos (tal como parar la base de datos), recuperar el contenido de un determinado archivo presente sobre el sistema de archivos del DBMS y en algunos casos emitir comandos al sistema operativo. Los ataques por inyección SQL son un tipo de ataque de inyección, en el cual los comandos SQL son insertados en la entrada de datos con la finalidad de efectuar la ejecución de comandos SQL predefinidos.

Modelamiento de la amenaza

  • Los ataques por inyección SQL permiten a los atacantes suplantar identidad, alterar datos existentes, causar problemas de repudio como anular transacciones o cambiar balances, permite la revelación de todos los datos en el sistema, destruir los datos o si no volverlos inasequibles, y convertirse en administradores del servidor de base de datos.
  • La inyección SQL es muy común con aplicaciones PHP y ASP debido a la prevalencia de interfaces funcionales obsoletas. Debido a la naturaleza de las interfaces programáticas disponibles, las aplicaciones J2EE y ASP.NET tienen menor probabilidad de ser fácilmente atacadas por una inyección SQL.
  • La gravedad de una inyección SQL está limitada por la habilidad e imaginación del atacante, y en menor medida a las contramedidas, como por ejemplo las conexiones con bajo privilegio al servidor de bases de datos, entre otras. En general, se considera a la inyección SQL de alto impacto.

Actividades de Seguridad Relacionadas

Cómo evitar las vulnerabilidades por inyección SQL

Ver en la Guía de OWASP el artículo sobre cómo evitar las vulnerabilidades por inyección SQL .
Ver Hoja de Tips para Prevenir la Inyeccion por SQL.

Cómo revisar el código para vulnerabilidades de inyección por SQL

Ver el artículo en la Guía de Revisión de Código OWASP sobre Cómo revisar el código para vulnerabilidades de inyección por SQL.

Cómo Probar las Vulnerabilidades de Inyección SQL.

Ver en la OWASP Testing Guide el artículo sobre cómo hacer Pruebas de Vulnerabilidad de Inyección SQL.

Descripción

Una inyección SQL ocurre cuando:

  1. Los datos ingresan en un programa desde una fuente que no es de confianza.
  2. Los datos construyen dinámicamente una consulta SQL.

Las principales consecuencias son:

  • Confidencialidad : Dado que las bases de datos SQL generalmente almacenan información sensible, la pérdida de la confiabilidad es un problema frecuente con las vulnerabilidades de inyección SQL.
  • Autenticación: Si se utilizan consultas SQL pobres para chequear nombres de usuarios u contraseñas, puede ser posible conectarse a un sistema como otro usuario sin conocimiento previo de la contraseña.
  • Autorización: Si la información de autorización es almacenada en una base de datos SQL, puede ser posible cambiar esta información mediante la explotación exitosa de una vulnerabilidad por inyección SQL.
  • Integridad: Así como puede ser posible leer información sensible, también es posible realizar cambios o incluso borrar esta información mediante un ataque por inyección SQL.

Factores de Riesgo

La plataforma afectada puede ser:

  • Lenguaje: SQL
  • Plataforma: Cualquiera (requiere de interacción con una base de datos SQL).

La inyección SQL se ha convertido en un problema común con sitios web que cuentan con base de datos. La falla es fácilmente detectada y fácilmente explotada, y como tal, cualquier sitio o paquete de software con incluso una mínima base de usuario es propenso a ser objeto de un intento de ataque de este tipo. Esencialmente, el ataque es llevado a cabo mediante la colocación de un meta carácter en los datos de entrada para colocar comandos SQL en el plano de control, el cual antes no existía. Este error depende del hecho de que SQL no hace real distinción entre los planos de datos y los de control.

Ejemplos

Example 1

En SQL:

select id, firstname, lastname from authors

Si uno proporciona:

Firstname: evil'ex
Lastname: Newman

La cadena de consulta se convierte en:

select id, firstname, lastname from authors where forename = 'evil'ex' and surname ='newman'
La cual la base de datos intenta ejecutar como:
Incorrect syntax near il' as the database tried to execute evil. 

Una versión segura de la anterior instrucción SQL podría ser codificada en Java como:

String firstname = req.getParameter("firstname");
String lastname = req.getParameter("lastname");
// FIXME: do your own validation to detect attacks
String query = "SELECT id, firstname, lastname FROM authors WHERE forename = ? and surname = ?";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, firstname );
pstmt.setString( 2, lastname );
try
{
	ResultSet results = pstmt.execute( );
}

Ejemplo 2

El siguiente código C# dinámicamente construye y ejecuta una consulta SQL que busca ítems que concuerden con un nombre específico. La consulta restringe los ítems mostrados a aquellos en los que el propietario concuerda con el username del usuario actualmente autenticado.

	...
	string userName = ctx.getAuthenticatedUserName();
	string query = "SELECT * FROM items WHERE owner = "'" 
					+ userName + "' AND itemname = '"  
					+ ItemName.Text + "'";
	sda = new SqlDataAdapter(query, conn);
	DataTable dt = new DataTable();
	sda.Fill(dt);
	...

La consulta que este código intenta ejecutar es:

	SELECT * FROM items
	WHERE owner = 
	AND itemname = ;

Sin embargo, dado que la consulta es construida dinámicamente concatenando una cadena de consulta base constante y una cadena ingresada por el usuario, la consulta solo funciona correctamente si itemName no contiene un carácter de comilla simple. Si un atacante con el nombre de usuario wiley ingresa la cadena “name’ OR ‘a’=’a” para itemName, entonces la consulta se convierte en lo siguiente:

	SELECT * FROM items
	WHERE owner = 'wiley'
	AND itemname = 'name' OR 'a'='a';

La adición de la condición OR ‘a’=’a’ causa que la clausula where siempre sea evaluada como verdadera, de este modo la consulta se vuelve lógicamente equivalente a la mucho más simple consulta:

	SELECT * FROM items;

La simplificación de la consulta permite al atacante evitar el requerimiento de que la consulta solamente retorne ítems pertenecientes al usuario autenticado; la consulta ahora retorna todas las entradas almacenadas en la tabla de ítems, sin tener en cuenta al propietario especificado.

Ejemplo 3

Este ejemplo examina los efectos de un valor malicioso diferente pasado a la consulta construida y ejecutada en el ejemplo 1. Si un atacante con el nombre de usuario hacker ingresa la cadena "hacker'); DELETE FROM items; --" for itemName, la consulta se convierte en las siguientes dos consultas:

	SELECT * FROM items 
	WHERE owner = 'hacker'
	AND itemname = 'name';

	DELETE FROM items;

	--'

Muchos servidores de base de datos, incluyendo Microsoft® SQL Server 2000, permiten múltiples sentencias SQL separadas por punto y coma ser ejecutadas a la vez. Aunque la cadena de este ataque resulta en un error en Oracle y otros servidores de base de datos que no permiten la ejecución en batch de sentencias separadas por punto y coma, en bases de datos que sí permiten la ejecución en batch, este tipo de ataque permite al atacante ejecutar comandos arbitrariamente contra la base de datos.

Note el par de guiones consecutivos, los cuales especifican a la mayoría de servidores de bases de datos que lo restante de la sentencia es tratado como un comentario y no se ejecuta. En este caso el carácter de comentario sirve para remover la posterior comilla simple sobrante de la consulta modificada. En una base de datos donde no se permite usar comentarios de este modo, el ataque general podría continuar siendo efectivo usando un truco similar al mostrado en el Ejemplo 1. Si un atacante ingresa la cadena “name’); DELETE FROM ítems; SELECT * FROM ítems WHERE 'a'='a", las siguientes tres sentencias válidas serán creadas:

	SELECT * FROM items 
	WHERE owner = 'hacker'
	AND itemname = 'name';

	DELETE FROM items;

	SELECT * FROM items WHERE 'a'='a';

Un método tradicional para prevenir ataques por inyección SQL es manejarlos como un problema de validación de entrada y aceptar solamente caracteres de una lista blanca de valores seguros o identificar y evadir una lista negra de valores potencialmente maliciosos. El Whitelisting puede ser un medio muy eficaz para hacer cumplir estrictas reglas de validación de entrada, sin embargo las sentencias SQL parametrizadas requieren menor mantenimiento y puede ofrecer mas garantías con respecto a la seguridad. Como es casi siempre el caso, el blacklisting está plagado de lagunas que hacen inefectivo prevenir los ataques por inyección SQL. Por ejemplo, los atacantes pueden:

  • Tomar como objetivo a campos que no se encuentran citados.
  • Encontrar maneras para evadir la necesidad de ciertos meta-caracteres.
  • Usar procedimientos almacenados para ocultar los meta-caracteres inyectados

Evadir manualmente caracteres en la entrada para consultas SQL puede ser útil, pero esto no hace a su aplicación segura ante ataques de inyección SQL. Otra solución comúnmente propuesta para tratar con los ataques por inyección SQL es la utilización de procesos almacenados. Si bien los procedimientos almacenados previenen algunos tipos de ataques por inyección SQL, fracasan al proteger contra muchos otros. Por ejemplo, el siquiente procedimiento PL/SQL es vulnerable a la misma inyección SQL mostrada en el primer ejemplo.

	procedure get_item (
		itm_cv IN OUT ItmCurTyp,
		usr in varchar2,
		itm in varchar2)
	is
		open itm_cv for ' SELECT * FROM items WHERE ' ||
				'owner = '''|| usr || 
				' AND itemname = ''' || itm || '''';
	end get_item;

Los procedimientos almacenados típicamente ayudan a prevenir ataques por inyección SQL limitando los tipos de sentencias que pueden ser pasadas a sus parámetros. Sin embargo, hay muchas maneras en torno a las limitaciones y muchas sentencias interesantes que todavía pueden ser pasadas a los procedimientos almacenados. Una vez más, los procedimientos almacenados pueden provenir algunas explotaciones, pero no harán a su aplicación segura contra ataques de inyección SQL.

Agentes de Amenaza Relacionados

Ataques Relacionados

Vulnerabilidades Relacionadas

Related Controls

Referencias