La inyección SQL es un método de ataque común en sitios web y puede ser utilizado para atacar cualquier tipo de base de datos SQL. Los daños que causa la inyección SQL son muchos e incluyen, entre otros:
- Divulgación de la identidad y contraseña del usuario
- Manipulación de datos existentes
- Interferencia con las transacciones del sistema, como cambiar los saldos de las cuentas
- Divulgación de todos los datos en el sistema
- Destrucción de los datos
- Hacer los datos no disponibles
- Tomar el control del servidor de la base de datos obteniendo privilegios administrativos
Para defenderse contra los ataques de inyección SQL, es importante implementar medidas de seguridad adecuadas. Un enfoque es utilizar una función escalar T-SQL definida por el usuario que verifique la cadena de entrada en busca de palabras clave sospechosas que puedan indicar intenciones de inyección SQL.
La función verifica la cadena de entrada contra un conjunto de palabras clave predefinidas que se sabe que se utilizan en casos de inyección SQL. Estas palabras clave incluyen palabras clave de modificación de datos, comandos de lenguaje de definición de datos SQL, prefijos comunes de procedimientos almacenados y procedimientos almacenados extendidos, signos de comentario y concatenación, palabras clave de flujo de control, palabras clave de control de transacciones, funciones de conjunto de datos, palabras clave de control de lotes, comandos de control del servidor y más.
Aquí hay un ejemplo de una función definida por el usuario que verifica la inyección SQL:
CREATE FUNCTION dbo.VerifySQLInjection (@TSQL varchar(max))
RETURNS bit
AS
BEGIN
DECLARE @IsSQLInjectionSuspected bit;
DECLARE @pos int;
SET @pos = 0;
SELECT @pos += CHARINDEX(lower(word), lower(@TSQL))
FROM ReservedWords;
SET @IsSQLInjectionSuspected = CASE WHEN (@pos > 0) THEN 1 ELSE 0 END;
RETURN @IsSQLInjectionSuspected;
END
La función toma una cadena T-SQL dinámica varchar(max) como entrada y devuelve un valor bit. Si la función detecta alguna de las palabras reservadas en la cadena de entrada, devuelve 1, lo que indica una posible inyección SQL. De lo contrario, devuelve 0.
Para utilizar esta función, debes crear una tabla llamada ReservedWords en la base de datos master y llenarla con la lista de palabras sospechosas. Aquí hay un ejemplo de cómo crear la tabla:
CREATE TABLE ReservedWords (
id int identity not null PRIMARY KEY,
word varchar(20)
);
INSERT INTO ReservedWords VALUES
('alter'), ('begin'), ('break'), ('checkpoint'), ('commit'), ('create'), ('cursor'), ('dbcc'), ('deny'), ('drop'), ('escape'), ('exec'), ('execute'), ('insert'), ('go'), ('grant'), ('opendatasource'), ('openquery'), ('openrowset'), ('shutdown'), ('sp_'), ('tran'), ('transaction'), ('update'), ('while'), ('xp_'), (';'), ('--');
Una vez que la función y la tabla estén configuradas, puedes utilizar la función VerifySQLInjection para verificar la inyección SQL en tus declaraciones T-SQL dinámicas. Aquí hay algunos ejemplos:
SELECT master.dbo.VerifySQLInjection('select productname from Northwind.dbo.products'); -- Devuelve 0
SELECT master.dbo.VerifySQLInjection('alter table Northwind.dbo.products alter column photo varbinary(max)'); -- Devuelve 1
SELECT master.dbo.VerifySQLInjection(';shutdown'); -- Devuelve 1
SELECT master.dbo.VerifySQLInjection('exec sp_helpdb'); -- Devuelve 1
Al implementar esta función definida por el usuario, puedes agregar una capa adicional de seguridad a tus aplicaciones de SQL Server y protegerte contra ataques de inyección SQL.