Скажем, у вас есть каталог товаров для вашего веб-размера, и ваша страница поиска позволяет осуществлять поиск по названию, описанию, цвету и размеру (скажем, вы продаете бюстгальтеры):
create table [products] (
product_id int identity(1,1) not null primary key
, name varchar(256)
, description varchar(max)
, color varchar(256)
, size varchar(256));
GO
create procedure usp_dynamicSearch
@product varchar(256) = NULL
, @description varchar(256) = NULL
, @color varchar(256) = NULL
, @size varchar(256) = NULL
as
begin
set nocount on;
declare @sql nvarchar(max)
, @and nvarchar(5);
set @sql = N'SELECT
product_id, name, description, color, size
FROM products
WHERE ';
set @and = N'';
if (@product is not null)
begin
set @sql = @sql + N'name LIKE ''' + @product + N'''';
set @and = N' AND ';
end
if (@description is not null)
begin
set @sql = @sql + @and + N'description LIKE ''' + @description + N'''';
set @and = N' AND ';
end
if (@color is not null)
begin
set @sql = @sql + @and + N'color = ''' + @color + N'''';
set @and = N' AND ';
end
if (@size is not null)
begin
set @sql = @sql + @and + N'size = ''' + @size + N'''';
end
exec sp_executesql @sql;
end
GO
Вы используете хранимую процедуру, которая динамически создает SQL, подходящий для поиска. Вы вызываете его, передавая параметры:
exec usp_dynamicSearch @color = N'Red', @size = N'58-DD';
Поскольку процедура создает небрежный динамический SQL, она все еще открыта для внедрения SQL:
exec usp_dynamicSearch @color = N'Red', @size = N''';
INSERT INTO products (name, description)
values (''31337'', ''haxorz!'');
--';
Нежелательный продукт был помещен в каталог (чтобы сделать это атакующей атакой ...). В этом случае подходящим исправлением является использование параметров и в динамическом SQL, а затем передача параметров в вызов sp_executesql
:
alter procedure usp_dynamicSearch
@product varchar(256) = NULL
, @description varchar(256) = NULL
, @color varchar(256) = NULL
, @size varchar(256) = NULL
as
begin
set nocount on;
declare @sql nvarchar(max)
, @and nvarchar(5);
set @sql = N'SELECT
product_id, name, description, color, size
FROM products
WHERE ';
set @and = N'';
if (@product is not null)
begin
set @sql = @sql + N'name LIKE @product';
set @and = N' AND ';
end
if (@description is not null)
begin
set @sql = @sql + @and + N'description LIKE @description';
set @and = N' AND ';
end
if (@color is not null)
begin
set @sql = @sql + @and + N'color = @color';
set @and = N' AND ';
end
if (@size is not null)
begin
set @sql = @sql + @and + N'size = @size';
end
exec sp_executesql @sql , N'@product varchar(256)
, @description varchar(256)
, @color varchar(256)
, @size varchar(256)'
, @product, @description, @color, @size;
end
GO
Таким образом, sp_executesql и динамический SQL являются главной задачей. Помимо этого, существуют также различные системные процедуры, которые создают динамический SQL под прикрытием, и исторически некоторые из них оказались уязвимыми, особенно в SQL 2000.