2

我的 VB.net 页面有一个文本框,它接受 SQL 语句并使用 SQL Helper 的 ExecuteDataSet 命令返回一个数据集。您认为防止执行 Delete、Truncate、Drop、Insert 等语句的最佳方法是什么?文本框应该只接受 Select 语句。我正在考虑通过 Javascript 或通过服务器验证来捕获输入字符串,但我确信有更有效的想法可以做到这一点。提前致谢。

编辑:我的文本框就像一个查询分析器,因此它接受一行 SQL 语句,然后根据输入的字符串返回一个数据集

4

4 回答 4

5

首先,让我郑重声明,你的设计是一个非常糟糕的主意;您正在使您的数据库面临巨大的风险。

更好的设计是让您的用户从他们可以选择的字段列表中进行选择。这避免了允许用户键入 SQL 语句。

但是,如果您绝对决心这样做,那么请构建一个您要阻止的关键字数组。然后,在用户输入之后,循环遍历数组,检查是否有任何被阻塞的单词。如果找到任何被阻止的词,则不执行 SQL。

不过,这是个坏主意。你不应该这样做。

于 2013-03-15T03:40:38.290 回答
1

有很多方法可以做到这一点,但我通常只是使用带参数的 sp_executesql 编写动态 sql。这是来自 BOL 的示例。

DECLARE @IntVariable int;
DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);

/* Build the SQL string one time.*/
SET @SQLString =
     N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID
       FROM AdventureWorks2008R2.HumanResources.Employee 
       WHERE BusinessEntityID = @BusinessEntityID';
SET @ParmDefinition = N'@BusinessEntityID tinyint';
/* Execute the string with the first parameter value. */
SET @IntVariable = 197;
EXECUTE sp_executesql @SQLString, @ParmDefinition,
                      @BusinessEntityID = @IntVariable;
/* Execute the same string with the second parameter value. */
SET @IntVariable = 109;
EXECUTE sp_executesql @SQLString, @ParmDefinition,
                  @BusinessEntityID = @IntVariable;

Sp_executesql 允许您将参数放入动态代码中,并且它们被视为变量。这样,如果有人试图将代码注入到字段中,他们“注入”的代码只会存储在列中。

于 2013-03-15T03:40:22.490 回答
1

防止 SQL 注入的一种方法是避免在代码中使用动态生成的 SQL。通过使用参数化查询和存储过程,您就不可能针对您的应用程序进行 SQL 注入。

通过传递参数,您可以避免许多类型的 SQL 注入攻击,保护数据库访问的更好方法是使用存储过程。存储过程可以通过将数据库中的对象限制为特定帐户并允许帐户仅执行存储过程来保护您的数据库。然后,您的代码使用仅有权执行存储过程的这一帐户进行所有数据库访问。您没有为该帐户提供任何其他权限,例如写入,这将允许攻击者输入 SQL 语句以对您的数据库执行

于 2013-03-15T04:23:43.690 回答
1

根据 DWRoeland 的回答,如果您坚持使用用户文本输入构建查询,则需要对输入进行大量筛选。

但是,与建议相反,我建议使用白名单方法:预先确定允许的关键字集合。筛选可接受的内容比尝试阻止所有不可接受的内容要容易得多。

只是一个额外的说明:
如果您选择下拉列表方法来构建查询,您仍然需要验证这些值,因为用户仍然可以在回发之前篡改这些值并对数据库造成严重破坏。

于 2013-03-15T04:51:54.967 回答