SQL-инъекция в SP_EXECUTESQL - PullRequest
1 голос
/ 17 апреля 2019

У меня есть хранимая процедура в SQL Server, которая получает XML в качестве входного параметра.В этом XML определяется - какая хранимая процедура, с какими параметрами должны выполняться значения.И в соответствии с тем, что хранимая процедура выполняет требуемую процедуру с использованием динамического SQL с sp_executesql.

Проблема в том, что значения параметров уязвимы для внедрения SQL.

Я пытался использоватьТипизированные параметры вот так:

EXEC sys.sp_executesql 
  @stmt = @sql, 
  @params = N'@Username SYSNAME, @HireDate DATE',
  @UserName = @Username, @HireDate = @HireDate;

Но в моем случае это не сработает, потому что я не знаю, какая процедура с какими параметрами будет выполняться.Количество параметров может варьироваться, и некоторые из них являются необязательными / имеют значения по умолчанию и т. Д. Все, что я могу получить, это имена параметров в виде строки :(

После некоторого анализа входного XML-кода SQL-запрос строитсяи выполняется так

declare @params nvarchar(max);
    select @params = coalesce(@params + N', ', N' ') + r.attrName + N' = ' + iif(p.isNumericType = 1, r.Value, '''' + r.Value /*cast(r.Value as nvarchar(max))*/ + '''') --+ r.Value
    from dbo.#ruleConfig r
        left join @spParams p on p.paramName = r.attrName -- datatype of a parameter from information_schema.parameters 

    declare @sql nvarchar(max) = (select @procName + isnull(@params, N''));

    exec dbo.sp_executesql @sql

Значение @sql может выглядеть примерно так:

'core.GetUser @LogonName = 'myDomain\myLogon''

Но также может выглядеть так:

'core.GetUser @fullLogonName = 'myDomain\myLogon;'WAITFOR DELAY '0:0:20';--'' and that's the problem.

1 Ответ

0 голосов
/ 24 апреля 2019

Начнем с того, что если у вас есть какая-либо функциональность, требующая отправки динамических команд выполнения хранимых процедур SQL, у вас есть большая проблема с вашим дизайном, так как со строгим тесно связанным проектом каждый вызов APIбудет сопоставлен с одной хранимой процедурой.

Если вы все еще хотите придерживаться текущего дизайна, то вам нужно создать список известных хранимых процедур и их значений.Вы не можете просто принять тот факт, что вы «не знаете, какая процедура с какими параметрами будет выполняться», потому что чем вы публикуете свой дизайн функциональности SQL-инъекций.

Вам необходимо создать перечисление известных сохраненныхпроцедуры (например, 1 = proc1, 2 = proc2 и т. д.) и выполняют проверку входных данных на основе регулярных выражений для их параметров.

В приведенном вами примере, если вы хотите, чтобы «myDomain \ myLogon»быть принятым и "myDomain \ myLogon; 'WAITFOR DELAY' 0: 0: 20 '; -" быть отклоненным, вы можете, например, использовать регулярное выражение, которое выглядит следующим образом:

^([A-Za-z\\])*$

Вы можетепротестируйте его на сайте regexr .Вам нужно будет создать регулярное выражение для проверки входных данных для каждого типа поля - например, имен, имен пользователей, электронных писем и т. Д. По сути, это очень похоже на создание отдельного API для каждого вызова процедуры с соответствующей проверкой ввода.

...