2017-10-11 73 views
1

对于我们ASP.NET(针对SQL Server)应用程序内的一些功能,我们允许员工用户指定WHERE子句。这个WHERE子句然后被添加到系统生成的SELECT语句的代码中以检索一些数据。保护数据输入SQL以防止不良行为

所以在本质上,我们结束了:

SELECT SomeFields FROM SomeTable WHEREUserEnteredWhere

其中大胆是系统和斜体是用户。这已经工作了一段时间,并给了我们一些很好的灵活性。

然而显然还有这里一个很大的问题,如果用户输入,其中:

SomeField = 1; DROP TABLE SomeTable;

目前唯一的验证语句是否与SELECT开始,将通过,因为我们将结束:

SELECT SomeFields FROM SomeTable WHERESomeField = 1; DROP TABLE SomeTable;

长期的解决办法是不允许用户输入SQL到文本框,但在短期内我要撑住这件事。

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

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

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

+1

限制接入是另一种方式。如果用户没有权限放弃,他不会放弃它。希望有人会添加更多的细节。 –

+0

我认为保存的方法是验证任何输入的单词,并检查输入的单词是否包含任何错误的动作命令,然后再将它传递到SQL查询中。 – Saif

+0

你如何“我们允许员工指定WHERE子句”?如果您允许用户传递一个键/值对列表,然后自己构造查询,该怎么办? asp.net服务帐户仍然有权限(另一个安全轴,您可以像别人提到的那样修复),最终用户实际上并不需要直接访问,是吗? – Tipx

回答

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' 
3

您知道正确的答案 - 您已将您的应用程序暴露给SQL注入。一般而言,特设解决方案并不健全。而且,把这个陈述放在交易中并没有帮助。毕竟,commit可能是其中的一个命令。

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

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

  • ;
  • update
  • delete
  • insert
  • create
  • exec
  • grant
  • 甚至更​​多
  • ,也可能select(除非你想支持子查询)

这可能会限制在一定程度上什么是允许的条件。

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

+0

最初我正在考虑禁止COMMIT并在交易中包装它。这样最终不会改变。不是很好,但更简单的检查比添加到永不结束的列表。 – TheEdge