C# 如何在为以后使用而设计的存储查询中防止Sql注入?自动化系统

C# 如何在为以后使用而设计的存储查询中防止Sql注入?自动化系统,c#,sql,asp.net,sql-server,C#,Sql,Asp.net,Sql Server,我正在使用一个.NETWebTool,我们的客户机需要一些非常大的查询,这对于我们的web服务器来说显然是不可行的。我们的解决方案是将查询返回到我们的自动化系统,并在查询完成时将数据反馈给用户。问题是,将查询从webtool传递到automation需要将查询存储为字符串以供以后使用。这不允许我们使用参数化输入 这里的最佳实践是什么?我们如何在运行此数据之前清除它?显然,最初应该验证输入,但我正在寻找一个更全面的解决方案 任何帮助都将不胜感激 求和: 为了让我更清楚,让我理解: 1) 您已经有了

我正在使用一个.NETWebTool,我们的客户机需要一些非常大的查询,这对于我们的web服务器来说显然是不可行的。我们的解决方案是将查询返回到我们的自动化系统,并在查询完成时将数据反馈给用户。问题是,将查询从webtool传递到automation需要将查询存储为字符串以供以后使用。这不允许我们使用参数化输入

这里的最佳实践是什么?我们如何在运行此数据之前清除它?显然,最初应该验证输入,但我正在寻找一个更全面的解决方案


任何帮助都将不胜感激

求和:

为了让我更清楚,让我理解:

1) 您已经有了通过webtool提供大型查询的用户

2) 您的webtool通过SQL server将它们提供给自动化系统

3) 使用SQL dynamic的自动化系统将查询结果并将结果反馈给用户

我假设您将在步骤2)中的每个单引号上放置两个单引号,以便将查询简化为“可存储”的内容

解决方案:

我认为如果不改变您的体系结构,在这一点上保护您自己和您的用户几乎是不可能的。但是如果你真的想保留它,你可以在这里做的最简单的事情就是在步骤1)中进行分析,并在步骤2)中存储查询而不进行任何编辑

示例:

我假设您已经有了自己的一套规则来分析您的查询,所以我将只讨论“存储查询”

有两条路要走。一种是不使用SQLServer像文件一样存储查询(这是最安全的解决方案,可能是性能最差的解决方案)


第二种方法是使用单引号字符的特殊替换,并在执行时转换回单引号字符(在有人使用替换字符之前是安全的)。

求和:

为了让我更清楚,让我理解:

1) 您已经有了通过webtool提供大型查询的用户

2) 您的webtool通过SQL server将它们提供给自动化系统

3) 使用SQL dynamic的自动化系统将查询结果并将结果反馈给用户

我假设您将在步骤2)中的每个单引号上放置两个单引号,以便将查询简化为“可存储”的内容

解决方案:

我认为如果不改变您的体系结构,在这一点上保护您自己和您的用户几乎是不可能的。但是如果你真的想保留它,你可以在这里做的最简单的事情就是在步骤1)中进行分析,并在步骤2)中存储查询而不进行任何编辑

示例:

我假设您已经有了自己的一套规则来分析您的查询,所以我将只讨论“存储查询”

有两条路要走。一种是不使用SQLServer像文件一样存储查询(这是最安全的解决方案,可能是性能最差的解决方案)


第二种方法是使用单引号字符的特殊替换,并在执行时转换回(在有人使用替换字符之前是安全的)。

问题中有一些假设需要验证,例如语句“我们将查询存储为字符串以供以后使用。这不允许我们使用参数化输入。“可以使用参数化查询,并将完整的SQL内容存储为字符串。以下是参数化查询的示例:

declare @sql nvarchar(max)
declare @monthNo int = 2
declare @minAmount decimal = 100

set @sql = N'select column1, column2 from dbo.Mytable where mon = @MonthNo and amount > @minAmount'
exec sp_executesql @sql, N'@monthNo int, @minAmount decimal', @monthNo, @minAmount 
如果上面的示例不是一个可行的选项,以下是一些用于捕获字符串中的注入尝试的语法:

-- check for sql injection
declare @sql nvarchar(max)
set @sql = N'My fancy sql query; truncate table dbo.VeryImportantTable'
IF CHARINDEX(';', ISNULL(@sql,'')) != 0 OR CHARINDEX('--', ISNULL(@sql,'')) != 0
BEGIN
 RAISERROR('Invalid input parameter', 16, 1)
 RETURN -1
END 

由于在代码或其实现的问题上没有示例,因此答案包含一定程度的推测。

问题中有一些假设需要验证,例如“我们将查询存储为字符串以供以后使用”的语句。这不允许我们使用参数化输入。“可以使用参数化查询,并将完整的SQL内容存储为字符串。以下是参数化查询的示例:

declare @sql nvarchar(max)
declare @monthNo int = 2
declare @minAmount decimal = 100

set @sql = N'select column1, column2 from dbo.Mytable where mon = @MonthNo and amount > @minAmount'
exec sp_executesql @sql, N'@monthNo int, @minAmount decimal', @monthNo, @minAmount 
如果上面的示例不是一个可行的选项,以下是一些用于捕获字符串中的注入尝试的语法:

-- check for sql injection
declare @sql nvarchar(max)
set @sql = N'My fancy sql query; truncate table dbo.VeryImportantTable'
IF CHARINDEX(';', ISNULL(@sql,'')) != 0 OR CHARINDEX('--', ISNULL(@sql,'')) != 0
BEGIN
 RAISERROR('Invalid input parameter', 16, 1)
 RETURN -1
END 

由于在代码或其实现的问题上没有示例,因此答案包含一定程度的推测。

这里的威胁模型是什么?您将查询存储在哪里?听起来您将查询存储在数据库中,并在以后再次执行。您是否担心有人修改存储的查询?如果这是您担心的,那么此时您的数据库可能已经被破坏,SQL注入是一个相当没有意义的问题……嘿,斯图尔特,谢谢。我不熟悉完成威胁模型,但我可以说我们的数据非常敏感,我们的应用程序是私有的,并且非常安全。@siyual,查询是在e webtool并存储在一个表中,该表设计用于保存它们以供以后使用。我们直接从webtool运行的任何查询都使用参数化变量,但这是唯一的,因为SQL存储为完整的stringSerialization?我假设这里涉及SqlDataAdapter对象。我不确定这些对象是否可以“开箱即用”序列化。“这里的威胁模型是什么?您将查询存储在哪里?听起来像是将查询存储在数据库中,然后在以后再次执行。您是否担心有人修改存储的查询?如果这正是您所担心的,那么此时您的数据库可能已经被破坏,SQL注入是一个相当没有意义的问题……嘿,斯图尔特,谢谢。我不熟悉完成威胁模型,但我可以说,我们的数据非常敏感,我们的应用程序是私有的,安全性很强。@siyual,查询是在webtool中生成的,并存储在