SQL Server tiene tantas cosas que aprender y siempre lo encuentro increíble. Mis conversaciones con los clientes a menudo surgen con preguntas de seguridad, especialmente sobre la inyección de SQL. Muchos han afirmado que SQL Injection es un problema de SQL Server. Me toma bastante tiempo hacerles saber que no hay nada sobre SQL Server y SQL Injection. SQL Injection es el resultado de prácticas de codificación incorrectas. Una de las recomendaciones que doy es sobre no usar Dynamic SQL. Puede haber algunas situaciones en las que no puedas evitarlo. Mi único consejo sería, evitar si es posible. En este blog, demostraría un problema de inyección de SQL debido a SQL dinámico y una posible solución que puede tener.
Supongamos que tenemos una página de búsqueda simple donde el usuario puede usar la búsqueda en blanco o proporcionar un filtro en cualquier campo. Hemos proporcionado dos campos para usar "Nombre" y "Apellido". El usuario escribe algo y presiona buscar. Aquí está nuestro código de procedimiento almacenado que se activa en segundo plano.
USE AdventureWorks2014 GO CREATE PROCEDURE search_first_or_last @firstName NVARCHAR(50) ,@lastName NVARCHAR(50) AS BEGIN DECLARE @sql NVARCHAR(4000) SELECT @sql = ' SELECT FirstName ,MiddleName, LastName' + ' FROM Person.Person WHERE 1 = 1 ' IF @firstName IS NOT NULL SELECT @sql = @sql + ' AND FirstName LIKE ''' + @firstName + '''' IF @lastName IS NOT NULL SELECT @sql = @sql + ' AND LastName LIKE ''' + @lastName + '''' EXEC (@sql) END
Si uso esta cadena para ejecutar en last name ”;drop table t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
La cadena dinámica sería
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
¿Ves el problema? Sí, los usuarios pueden eliminar la tabla t1 si el código se ejecuta en una cuenta con privilegios elevados.
Una de las soluciones al problema sería usar sp_executesql. Aquí está la mejor versión usando
CREATE PROCEDURE search_first_or_last @firstName NVARCHAR(50) ,@lastName NVARCHAR(50) AS BEGIN DECLARE @sql NVARCHAR(4000) SELECT @sql = ' SELECT FirstName , MiddleName, LastName' + ' FROM Person.Person WHERE 1 = 1 ' IF @firstName IS NOT NULL SELECT @sql = @sql + ' AND FirstName LIKE @firstName' IF @lastName IS NOT NULL SELECT @sql = @sql + ' AND LastName LIKE @lastName ' EXEC sp_executesql @sql ,N'@firstName nvarchar(50), @lastName nvarchar(50)' ,@firstName ,@lastName END
Espero que puedas usar esto e implementarlo en tu proyecto. ¿Está utilizando estas técnicas simples en su código de producción? ¿Alguna vez ha enfrentado problemas similares durante la auditoría? Déjame saber de tus aprendizajes.