2008-11-20 72 views

回答

19

即使你的问题是非常通用的,总有几个规则:

  • 使用参数化查询(SqlCommandSqlParameter),并把用户输入的参数。
  • 不要从未经检查的用户输入中构建SQL字符串。
  • 不要以为你可以建立一个消毒程序,可以检查用户输入的每一种格式错误。边缘情况很容易被遗忘。检查数字输入可能很简单,可以让您安全起见,但对于字符串输入只需使用参数。
  • 检查二级漏洞 - 如果这些值由用户输入组成,请不要从SQL表值中构建SQL查询字符串。
  • 使用存储过程来封装数据库操作。发生
+0

所有这些,除了最后一个之外,都是第一个隐含的(如果所有的输入通过使用准备好的语句(或参数化查询)正确地逃脱了),否?或者你认为存在细微的差异? – 2008-11-20 12:16:09

+1

不可以。但是,有人提出这类问题的可能性很大,但对这些问题的含义并没有明确的理解。让他们明确是​​支持理解。随着你的抽象经验和能力的提高,你不需要明确,而且你不可能再提出这样的问题。 – Tomalak 2008-11-20 14:14:12

+0

这是一个很好的答案,但我觉得“使用存储过程来封装数据库操作”是有误导性的。参数化动态SQL与参数化存储过程一样安全。为了清楚起见,也许你应该在答案中更加隐含。 – 2009-08-06 20:08:00

-4

尝试使用存储过程,并验证数据的输入。不要使用任何直接SQL,如INSERT INTO ...

+0

存储过程有没有关系,你可以通过不参数化呼叫以不安全的方式执行SP。 – Flory 2008-11-20 16:39:00

16

使用Prepared Statements(链接到一个ASP.NET教程,该教程使用'为产品添加节点'部分中的准备语句)。这里的所有都是它的。

那么,或者使用ORM,如Linq to SQLNHibernate,它们在内部使用预准备语句。

4

SQL注入,因为查询到数据库中实时地构建,例如:

SELECT * From Table1 WHERE " + UserInput 

UserInput可能是恶意的,并包含您不打算等说法。

要避免它,您需要避免将查询连接在一起。

您可以通过使用参数化查询来完成此操作 - 查看DBCommand对象以了解您的特定DB风格。

10

使用参数!它真的就是这么简单:-)

创建您的查询像这样(MS SQL Server的用C#):

SqlCommand getPersons = new SqlCommand("SELECT * FROM Table WHERE Name = @Name", conn); 

这里@Name是要避免SQL注入的参数,conn是一个SqlConnection对象。 然后添加你做下面的参数值:

getPersons.Parameters.AddWithValue("@Name", theName); 

这里theName是包含您正在搜索的名称的变量。

现在应该不可能对该查询执行任何sql注入。

由于这是这么简单,没有理由不使用参数。

3

斯科特·格思里posted a decent little article这个而回。在书中,他提供了保护自己5点建议:

  1. 不要构造动态SQL语句,而不使用类型安全参数编码机制。[...]

  2. 之前,请务必进行应用程序的安全性审核的把它放在生产,并建立一个正式的安全程序,审查所有的代码,你随时进行更新。[...]

  3. 决不存储在数据库中明文敏感数据。[...]

  4. 确保你写自动化单元测试验证具体数据访问层和应用程序不受SQL注入攻击。[...]

  5. 锁定你的数据库只授予Web应用程序访问它的最小权限集,它需要的功能。[...]

他没有解释的一份体面的工作,为什么这些都是重要的,并链接到其他一些资源,以及...

1

务必仅使用参数化查询。

2

永远不要信任用户输入,始终验证它,并使用sql参数。应该有足够的基础来防止SQL注入。

-2

了解究竟SQL注入是什么,然后从不写任何易受攻击的东西。

0

本书“构建安全的ASP.NET应用程序”指南在此主题上有一个section

3

使用参数化查询和/或存储过程并通过SQL参数解析参数。 永不通过连接字符串生成SQL代码。还请阅读关于SQL注入和关于编写安全代码的内容,因为防止SQL注入只是安全性的一小部分。还有更多(如XSS - 跨站点脚本)。如果黑客想要破坏您的网站/应用程序,他会寻找更多,然后只有SQL注入。

10

决不相信用户输入 - 使用验证控件,正则表达式,代码验证所有文本框条目,等等

不要使用动态SQL - 使用参数化的SQL或存储过程

决不使用管理级帐户连接到数据库 - 使用有限的访问帐户连接到数据库

D不要以纯文本存储秘密 - 加密或散列密码和其他敏感数据;您还应该加密连接字符串

例外情况应该泄漏最少的信息 - 不要在错误消息中泄露太多信息;使用customErrors在未处理错误的情况下显示最少的信息;一套调试MSDN上Stop SQL Injection

有用的链接

0

正如其他人说,不要将用户输入来创建动态的SQL语句;使用动态SQL时始终使用参数化SQL。不过我会指出,这个规则也适用于在存储过程中创建动态sql。这个事实是人们经常忽略的。他们认为他们是安全的,因为他们“使用存储过程”。

0

使用XSS Secured UrlEncode使用Microsoft.Security.Application.AntiXss.UrlEncode和SQL注入将不起作用。或者您可以使用ASP.NET - JSON - 序列化和反序列化

还可以使用Macfee Fre Tool中的SiteDigger测试您的应用程序。

几个来自here

.NET安全工具包1.0 .NETMon 1.0 Validator.NET 1.0

0

大家都说 “使用参数”。如果它不那么困难,我们不得不说不那么少。使用QueryFirst。连接的诱惑被删除,正确的方式成为最简单的方式。只需在SQL中输入@myParam创建一个参数,剩下的工具就完成了。

免责声明:我写QueryFirst