sp_execute_external_script и SQL-инъекция

Пересказ статьи Grant Fritchey. sp_execute_external_script and SQL Injection

Для того, чтобы иметь возможность использовать R и Python (а также Java в SQL Server 2019) непосредственно из ваших скриптов SQL Server, применяется процедура sp_execute_external_script. Когда вы видите этот код впервые, он напоминает sp_execute_sql. Первое, что приходит на ум, это «О, нет. Еще одно лазейка для проникновения SQL-инъекции.» У меня есть для вас несколько хороших и плохих новостей.

Это не SQL

Первое и самое важное — это понять, что мы не говорим тут об SQL. Давайте начнем с рассмотрения одного кода. Это непосредственный пример из документации Майкрософт:

DROP PROC IF EXISTS generate_iris_model;
GO
CREATE PROC generate_iris_model
AS
BEGIN
 EXEC sp_execute_external_script  
      @LANGUAGE = N'R'  
     , @script = N'  
          library(e1071);  
          irismodel <-naiveBayes(iris_data[,1:4], iris_data[,5]);  
          trained_model <- data.frame(payload = as.raw(serialize(irismodel, connection=NULL)));  
'  
     , @input_data_1 = N'select "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species" from iris_data'  
     , @input_data_1_name = N'iris_data'  
     , @output_data_1_name = N'trained_model'  
    WITH RESULT SETS ((model varbinary(MAX)));  
END;
GO

В этом виде код явно не может пострадать от SQL-инъекций; так что, мы все сделали правильно? Не совсем. Давайте немного исследуем его.

Начнем с @input_data_1, и т.д. Это выглядит как значения параметров. В теории мы можем добавлять параметры в эту процедуру, а затем предоставлять процедуре входные данные. Разве это не лазейка для SQL-инъекции?

Нет.

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

Но как же набор данных!

Внимательный взгляд позволит увидеть, что набор данных определяется на SQL. Так он страдает от инъекционных атак? Краткий ответ — нет. Если имеется более одного результирующего набора внутри кода Python, это вызовет ошибку. Поэтому тут вы защищены.

Это важно, поскольку запрос набора данных может определяться с параметрами. Вы можете передать значения через эти параметры, и вы, скорее всего, будете передавать значения через эти параметры из внешнего запроса или процедуры. И это не уязвимость?

Нет.

Замечательно. Это все хорошие новости, так?

Немного плохих новостей

Вы можете открыть одно направление атак. Это если вы параметризуете сам скрипт. Передать его как параметр в вашу процедуру. Никто не говорит, что вы должны использовать строку, как в данном примере. Вы можете просто предать код.

Если вы также позволяете отдельным пользователям печатать любой код, который они хотят, то найдутся те, кто попытается передать злонамеренный код через R, Python или Java. Однако, подобно реализации CLR, выполненной Майкрософт, этот код должен быть безопасным. Если вы пытаетесь сделать «плохой» код, он должен потерпеть неудачу.

Тем не менее, это немного беспокоит. Вам нужно будет убедиться, что вы делаете все стандартно, как вы обычно поступаете в других случаях. Вам по-прежнему потребуется дезинфицировать входные данные, чтобы уже в самом начале не было шансов для атаки. Следует также организовать защиту таким образом, чтобы ни одна учетная запись, с которой входит клиент, не была администратором сервера или sa. Помните, что следует предотвращать утечку данных.

Заключение

Меня спрашивали, имеется ли направление атаки для SQL-инъекций? Могу сообщить, что это не так. Существует вероятность того, что плохой актер получит какой-то проблемный код в вашей системе, который может выявить уязвимость. Тем не менее, вы должны были бы сделать огромное количество неудачных решений, чтобы такое произошло. Общая структура абсолютно предотвращает стандартную атаку SQL-инъекций, поэтому не стоит об этом беспокоиться.

Добавить комментарий