Microsoft SQL Server
SQL dinámico
Buscar..
Ejecutar la instrucción SQL proporcionada como una cadena
En algunos casos, necesitaría ejecutar una consulta SQL colocada en una cadena. EXEC, EXECUTE o el procedimiento del sistema sp_executesql puede ejecutar cualquier consulta SQL proporcionada como cadena:
sp_executesql N'SELECT * FROM sys.objects'
-- or
sp_executesql @stmt = N'SELECT * FROM sys.objects'
-- or
EXEC sp_executesql N'SELECT * FROM sys.objects'
-- or
EXEC('SELECT * FROM sys.columns')
-- or
EXECUTE('SELECT * FROM sys.tables')
Este procedimiento devolverá el mismo conjunto de resultados que la consulta SQL proporcionada como texto de declaración. sp_executesql puede ejecutar la consulta SQL proporcionada como literal de cadena, variable / parámetro, o incluso expresión:
declare @table nvarchar(40) = N'product items'
EXEC(N'SELECT * FROM ' + @table)
declare @sql nvarchar(40) = N'SELECT * FROM ' + QUOTENAME(@table);
EXEC sp_executesql @sql
Necesitas la función QUOTENAME para escapar de los caracteres especiales en la variable @table. Sin esta función, obtendría un error de sintaxis si la variable @table contiene algo como espacios, corchetes o cualquier otro carácter especial.
SQL dinámico ejecutado como usuario diferente
Puede ejecutar la consulta SQL como usuario diferente utilizando AS USER = 'nombre del usuario de la base de datos'
EXEC(N'SELECT * FROM product') AS USER = 'dbo'
La consulta SQL se ejecutará bajo el usuario de la base de datos dbo. Todas las verificaciones de permisos aplicables al usuario dbo se verifican en la consulta SQL.
Inyección de SQL con SQL dinámico
Las consultas dinámicas son
SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = ''' + @user + ''' AND Password = ''' + @pass + ''''
EXEC(@sql)
Si el valor de la variable de usuario es mi nombre de usuario '' OR 1 = 1 , se ejecutará la siguiente consulta:
SELECT COUNT(*)
FROM AppUsers
WHERE Username = 'myusername' OR 1=1 --' AND Password = ''
Los comentarios al final del valor de la variable @nombre de usuario comentarán una parte final de la consulta y se evaluará la condición 1 = 1. La aplicación que lo compruebe allí, al menos un usuario devuelto por esta consulta devolverá un conteo mayor que 0 y el inicio de sesión será exitoso.
Usando este método, el atacante puede iniciar sesión en la aplicación incluso si no conoce un nombre de usuario y contraseña válidos.
SQL dinámico con parámetros
Para evitar problemas de inyección y escape, las consultas de SQL dinámico deben ejecutarse con parámetros, por ejemplo:
SET @sql = N'SELECT COUNT(*) FROM AppUsers WHERE Username = @user AND Password = @pass
EXEC sp_executesql @sql, '@user nvarchar(50), @pass nvarchar(50)', @username, @password
El segundo parámetro es una lista de parámetros utilizados en la consulta con sus tipos, después de esta lista se proporcionan las variables que se utilizarán como valores de parámetros.
sp_executesql escapará de los caracteres especiales y ejecutará la consulta SQL.