如何在允许良性SQL注入的同时防止恶意SQL注入攻击?

时间:2013-04-04 16:29:16

标签: c# sql-server asp.net-mvc-4 sql-injection

我正在编写一个ASP.NET MVC4应用程序,它最终会动态构建一个SQL SELECT语句,以便以后存储和执行。动态SQL的结构由用户配置以用户友好的方式确定,具有标准复选框,下拉列表和自由形式文本框。使用参数化查询验证输入并构建SQL字符串是很简单的,除了我需要允许高级用户输入自定义SQL以直接注入SELECT和WHERE子句。那么我可以使用哪些技术来清理自定义SQL表达式或者防止来自聪明用户的不需要的输入?我可以很容易地解析字符串中的可疑关键字和黑名单插入/更新/删除/等等,但有些东西告诉我,这不会100%保护我。

我很高兴提供有关我在这里做什么的更多详细信息,但我不确定其他哪些细节会有所帮助,因为我觉得我的问题虽然可能不常见,但却非常通用。< / p>

4 个答案:

答案 0 :(得分:10)

与其他观点相反, 可以安全地执行此操作(只需查看Data Explorer)。以下是您可以采取的四项措施:

帐户安全

Sql Server将允许您限制用于建立与数据库连接的帐户的可用权限。仅授予读取权限,并且仅授予适当的表。然后有人可以注入恶意代码直到它们是蓝色的,但它会在编译步骤失败,因为它们没有足够的权限。这可能意味着为此访问使用不同的连接字符串而不是应用程序的其他部分。

请注意,这对sql代码很有用,但也有其他类型的注入。如果您在运行之前将页面上的查询(完整或部分)显示给用户,您还应该注意javascript注入攻击,例如跨站点脚本。

查询总督

您还希望抵御拒绝服务攻击。即使是意外,只需构建一个低效的查询,Sql数据库也可以轻松实现这些。要解决此威胁,您应该查看Sql Server中的query governor功能。请注意,调整这个人很棘手。

隔离

最安全的方法是使用托管在专用服务器上的专用的,经过清理的报告数据库。这可确保在性能或违反的服务器或帐户方面,任何查询都不会影响生产。 sql server中有一些功能,例如SSIS,可用于自动化生产中的报告数据库。

使用产品

关于安全性的一个问题是,永远不会想要建立自己的安全系统。创建似乎有用的东西,通过测试很容易,但是以微妙的方式存在缺陷,导致后来的破坏。您希望依靠来自供应商的产品来做这种事情作为核心竞争力,并且可以提供支持和一定程度的赔偿。通常我会在身份验证系统方面讨论这个问题,但是这个规则也适用于sql注入防御。

在这种情况下,可能值得查看Stack Overflow的Data Explorer。这是一个允许不受信任的用户构造任意查询的工具。该项目是open source,因此您可以亲眼看看他们为确保安全所做的工作,甚至只是为了您自己的用途而分配该项目。值得一提的是,该工具的安全性的很大一部分是它旨在用于专用的,经过消毒的数据库,因此它不会使您免于其他项目。

尽管如此,我认为建立一些观点并通过报告服务提供访问权的评论可能是您最好的选择。

答案 1 :(得分:4)

我认为您只能通过而不是提供指定SQL的直接方式来实现您的需求。

然而,这不一定是个问题。基本上,您只需要SQL的子集来定义表达式(在SELECT中计算的solumns)和谓词(在WHERE中进行过滤)。这可以通过一个自制的解析器来处理,该解析器具有足够的能力来完成所需的一切,但是然后将表达式“编译”成真正的SQL代码,而不直接注入任何东西。

然后验证语法并确保不能构造允许任何注入的构造。此外,它允许您正确地让代码生成器根据需要参数化您生成的查询(例如,您的代码生成器可以将所有文字作为查询参数传入)。

答案 2 :(得分:1)

我永远不会让用户对生产服务器运行自定义SQL语句。 哪些坏人可以直接尝试读取/写入/修改他们不应该使用的表,或者其他坏人可能会破坏弱账户并对您的服务器运行SQL语句。

如果你有预先构建的系统根据html输入创建sql语句,那么你可以在后端生成脚本,这不会伤害你的数据库。否则,如果用户想要非常自定义的内容,那么让他们上传他们的脚本,与SQL管理员一起检查并确保它“安全执行”并运行它以进行安排。

如果脚本被拒绝,请让用户知道它,并解释为什么他们的自定义脚本被拒绝。

答案 3 :(得分:0)

使用存储过程,因此来自任何用户的任何内容都将作为参数插入,永远不会被执行。