我们如何通过正则表达式或任何其他方式防止SQL注入 asp.net

How to we prevent SQL Injection by Regular Expression or any other way in asp.net

提问人:Jaihind 提问时间:3/14/2019 最后编辑:Tetsuya YamamotoJaihind 更新时间:3/15/2019 访问量:169

问:

在我问之前 - 我知道存储过程是防止 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

提前致谢。

sql-server t-sql sql 注入

评论

5赞 Thom A 3/14/2019
您也可以参数化动态语句。但是,在没有看到问题代码的情况下,我们如何帮助您确保其安全?
0赞 Steve 3/14/2019
您的“动态查询”示例在哪里?你的问题与“正则表达式”有什么关系?
0赞 Damien_The_Unbeliever 3/14/2019
是的,对于防止注射真正重要的参数。而不是它们是否被存储的过程或其他查询使用。如果您需要参数化不可参数化的项目(例如表名或列名),请使用可接受值的白名单
0赞 Jaihind 3/14/2019
@Larnu 我不想使用 parametrise 语句。我想知道像正则表达式或任何 jquery/javascript 插件这样的前端验证
3赞 Steve 3/14/2019
现在我的问题是:为什么需要像在动态 sql 中一样转换一个简单的查询?Select * FROM Business WHERE ProductID = @Product AND BusinessName = @BusinessName

答:

3赞 Zohar Peled 3/14/2019 #1

我真的希望你发布的过程不是你在生产环境中使用的过程,因为它根本不安全。您使用参数的事实并不意味着您不会受到 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 注入的影响,而答案中的过程则以预期使用的方式使用参数 - 作为参数。

评论

0赞 Zohar Peled 3/14/2019
@Damien_The_Unbeliever谢谢!
0赞 Jaihind 3/14/2019
@ZoharPeled感谢您的回复,这对我有帮助,但我想知道一些前端验证来停止 sql 注入,例如 jquery 验证或正则表达式。
0赞 Zohar Peled 3/14/2019
清理输入并不是防止 SQL 注入的完全证明的方法。参数是(好吧,至少在正确使用的情况下)。如果您发现需要查询未知的表或列(无法参数化),则可以将其列入白名单,如本答案所示。QUOTENAME