保护数据进入SQL以防止不良行为

时间:2017-10-11 01:40:19

标签: c# sql asp.net sql-server

对于ASP.NET(针对SQL Server)应用程序内部的一些功能,我们允许员工用户指定WHERE子句。然后将此WHERE子句在代码中附加到系统生成的SELECT语句以检索某些数据。

所以从本质上讲,我们最终得到:

  

SELECT SomeFields FROM SomeTable WHERE UserEnteredWhere

粗体是系统,斜体是用户。这已经工作了很长时间,并给了我们一些很好的灵活性。

然而,如果用户输入以下内容,显然存在一个很大的问题:

  

SomeField = 1; DROP TABLE SomeTable;

目前唯一的验证是语句是否以SELECT语言开头,因为我们最终会得到:

  

SELECT SomeFields FROM SomeTable WHERE SomeField = 1; DROP TABLE SomeTable;

长期解决方案是不允许用户将SQL输入到文本框中,但在短期内我想要支持它。

我能想到的唯一解决方案是在交易中运行每个请求,以确保不会造成长期损害。

有没有人有任何关于如何验证用户输入“where子句”的建议,以确保它在执行之前没有任何DDL内容?

PS。我确实意识到上述情况很糟糕,不应该这样做,但这是我在遗留系统中所拥有的(我没有写),所以请尽量帮助我解决问题,而不是告诉我不要这样做。 : - )

2 个答案:

答案 0 :(得分:3)

您知道正确答案 - 您已将应用程序暴露给SQL注入。通常,ad-hoc解决方案不健壮。并且,将该陈述置于交易中并没有帮助。毕竟,commit可能是其中一个命令。

某些界面具有“执行单个查询”的等效功能。这几乎可以解决您的问题,因为第二个查询会在应用程序中生成错误。

我建议不要在用户生成的条件中允许以下任何字符/单词:

  • ;
  • update
  • delete
  • insert
  • create
  • exec
  • grant
  • 可能还有更多
  • 也可能select(除非您想支持子查询)

这可能会在某种程度上限制条件允许的内容。

这不是对注射的保证,而是应该让事情变得更好的事情。

答案 1 :(得分:1)

由于我需要快速修复,我最终最终从SQL Server方面解决了这个问题:

  • 通过在.NET中为这些数据库使用单独的连接 互动。 Ť
  • 用户被锁定为仅允许SELECT 声明如下:

SQL:

CREATE LOGIN MrReadOnly
    WITH PASSWORD = 'LetMeIn!';

USE MyDatabase;
CREATE USER MrReadOnly FOR LOGIN MrReadOnly;
GO 

EXEC sp_addrolemember N'db_datareader', N'MrReadOnly'