SQL инъекция в SQL Server хранимой процедуры - PullRequest
0 голосов
/ 18 сентября 2018

В моей процедуре ниже, как я могу проверить SQL-инъекцию для параметров @ TECHNOLOGY, @ CURE, @ APPLICATION? Пожалуйста, помогите

CREATE PROCEDURE [dbo].[SEARCH]
 @PRODUCTNAME NVARCHAR(500),
 @TECHNOLOGY NVARCHAR(200),
 @CURE NVARCHAR(200),
 @APPLICATION NVARCHAR(200)
AS
 SELECT DISTINCT PM.F_PRODUCT AS ID,
  PM.F_PRODUCT_NAME AS [NAME],
  PM.F_FORMAT AS FMT,
  PM.F_SUBFORMAT AS SFMT,
  STUFF((SELECT DISTINCT ', ' + CAST(F_LANGUAGE AS VARCHAR(200)) FROM T_PDF_MSDS PD
    WHERE PD.F_PRODUCT = PM.F_PRODUCT AND PD.F_FORMAT = PM.F_FORMAT AND PD.F_SUBFORMAT = PM.F_SUBFORMAT
    FOR XML PATH('')),1,1,'') AS LANG,
  PM.F_DOC_PATH AS DPATH,
  CONVERT(VARCHAR,PM.F_PUBLISHED_DATE,120) AS PDATE,
  SUBSTRING(PM.F_CUSTOM1, CHARINDEX(':',PM.F_CUSTOM1)+1, LEN(PM.F_CUSTOM1)) AS TECHNOLOGY,
  SUBSTRING(PM.F_CUSTOM2, CHARINDEX(':',PM.F_CUSTOM2)+1, LEN(PM.F_CUSTOM2)) AS CURE,
  SUBSTRING(PM.F_CUSTOM3, CHARINDEX(':',PM.F_CUSTOM3)+1, LEN(PM.F_CUSTOM3)) AS [APPLICATION],
  'PDF' AS DOC
 FROM T_PDF_MSDS PM
 WHERE
  --(@PRODUCTNAME IS NULL OR REPLACE(REPLACE(REPLACE(REPLACE(PM.F_PRODUCT_NAME,'™','|TM'),'®','|TS'),'©','|CP'),'°','|DEG')
   --LIKE REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@PRODUCTNAME,'[','\['),'_','\_'),'™','|TM'),'®','|TS'),'©','|CP'),'°','|DEG') ESCAPE '\')
 (@TECHNOLOGY = '-1' OR PM.F_CUSTOM1 LIKE '%' + @TECHNOLOGY + '%')
  AND (@CURE = '-1' OR PM.F_CUSTOM2 LIKE '%' + @CURE + '%')
  AND (@APPLICATION = '-1' OR PM.F_CUSTOM3 LIKE '%' + @APPLICATION + '%')
  AND PM.F_AUTHORIZED IN (-1,1,3)
 GROUP BY PM.F_PRODUCT, PM.F_PRODUCT_NAME, PM.F_FORMAT, PM.F_SUBFORMAT, PM.F_DOC_PATH, PM.F_PUBLISHED_DATE, PM.F_CUSTOM1, PM.F_CUSTOM2, PM.F_CUSTOM3
;

возможна ли любая инъекция sql в описанной выше процедуре?

1 Ответ

0 голосов
/ 18 сентября 2018

Внедрение SQL обычно, когда команда SQL строится с использованием неанизированных входных данных.Например ...

var sql = "SELECT * FROM MYTABLE WHERE MYCOLUMN = " + txtInput.Text;
var cmd = new SqlCommand(sql);
...

Используя хранимую процедуру в том виде, в каком она у вас есть, вы эффективно защищаете себя от этого.


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

var sql = "EXEC MySproc '" + txtInput.Text + "'";
var cmd = new SqlCommand(sql);
...

Правильный способ сделать это - убедиться, что вы используетепараметризованная команда, такая как ...

var cmd = new SqlCommand("MySproc", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@MyParam", SqlDbType.NVarChar, 200));
cmd.Parameters["@MyParam"].Value = txtInput.Text;
...

В ответ на комментарий ОП (который, я считаю, находится в пределах исходного вопроса) ...

Также возможно стать жертвой SQL-инъекции за счет использования динамического SQL в хранимой процедуре.Например ...

CREATE PROCEDURE [dbo].[MySproc]
   @MyParam NVARCHAR(200),
   @MyParam2 INT
AS
BEGIN
  DECLARE @SQL NVARCHAR(1000)
  SET @SQL = N'SELECT * FROM [MyTable] WHERE [MyColumn] = ''' + @MyParam + N''''
  EXEC sp_executesql @SQL
END

Чтобы защитить себя, вы должны параметризовать каждую передаваемую переменную в sp_executesql ...

DECLARE @SQL NVARCHAR(1000)
SET @SQL = N'SELECT * FROM [MyTable] WHERE [MyColumn] = @MyParamInner'
EXEC sp_executesql @SQL, N'@MyParamInner NVARCHAR(200)', @MyParam

Обратите внимание, выНЕ следует заключать @MyParamInner в кавычки в предложении where, даже если это символьная переменная

Если вам нужно передать несколько значений, вы обновите его до чего-то вроде ...

DECLARE @SQL NVARCHAR(1000)
SET @SQL = N'SELECT * FROM [MyTable] WHERE [MyColumn] = @MyParamInner AND [MyColumn2] = @MyParam2Inner'
EXEC sp_executesql @SQL, N'@MyParamInner NVARCHAR(200), @MyParam2Inner INT', @MyParam, @MyParam2
...