在我询问之前-我确实知道存储过程是防止sql注入的最佳方法。我们可以通过参数化存储过程来实现。
但是在我的应用程序中,我也在可能进行sql注入的存储过程中使用动态查询。
请建议我一种停止sql注入的方法,就像任何正则表达式或其他方法一样。 示例:
CREATE PROCEDURE [dbo].[USP_BusinessSearch]
@Product INT = NULL,
@BusinessName VARCHAR(100) = NULL
AS
DECLARE @AdditionalCriteria AS NVARCHAR(MAX)
DECLARE @BaseQuery AS NVARCHAR(MAX)
BEGIN
SET NOCOUNT ON
SET @BaseQuery = 'Select * FROM Business WHERE ProductID = ' + @Product
SET @AdditionalCriteria = ' AND BusinessName = '+@BusinessName+' '
SET @BaseQuery = @BaseQuery + @AdditionalCriteria
EXEC SP_EXECUTESQL @BaseQuery
END
谢谢。
答案 0 :(得分:3)
我真的希望您发布的过程不是在生产环境中使用的过程,因为它根本不安全。使用参数的事实并不意味着您可以安全使用SQL注入-这就是您使用参数的方式。可以在不使用动态SQL的情况下编写此过程,这样可以防止SQL注入,如下所示:
CREATE PROCEDURE [dbo].[USP_BusinessSearch]
@Product INT = NULL,
@BusinessName VARCHAR(100) = NULL
AS
SELECT *
FROM Business
WHERE ProductID = @Product
AND BusinessName = @BusinessName
请注意,这并不意味着任何动态SQL方法都容易受到SQL注入的攻击-如果需要,很有可能使用动态SQL来防止SQL注入:
CREATE PROCEDURE [dbo].[USP_BusinessSearch]
@Product INT = NULL,
@BusinessName VARCHAR(100) = NULL
AS
DECLARE @ParamDefinition AS NVARCHAR(MAX)
DECLARE @BaseQuery AS NVARCHAR(MAX)
SELECT @BaseQuery = N'Select * FROM Business WHERE ProductID = @Product AND BusinessName = @BusinessName',
@ParamDefinition = N'@Product INT, @BusinessName VARCHAR(100)'
EXEC SP_EXECUTESQL @BaseQuery, @ParamDefinition, @Product, @BusinessName
END
此方法与问题中的过程之间的主要区别在于,问题中的查询只是将参数值连接到动态SQL中,从而使其易于受到SQL注入的影响,而答案中的过程则使用参数它们的预期使用方式-作为参数。