SQLParameter如何阻止SQL注入?

Abe*_*ler 72 .net sql-server security

在后台究竟发生了什么使SQLParameter阻止了.NET参数化查询中的SQL Inection攻击?它只是剥离任何可疑的角色还是还有更多的东西?

有人在那里检查,看看当你传递恶意输入时实际上到达SQL Server的是什么?

相关:您可以在SQL FROM语句中使用SQLParameter吗?

Kei*_*thS 75

基本上,当您执行SQLCommandusing时SQLParameters,参数永远不会直接插入到语句中.相反,调用一个调用的系统存储过程sp_executesql并给出SQL字符串和参数数组.

当这样使用时,参数被隔离并被视为数据,而不是必须从语句中解析出来(因此可能会改变它),因此参数包含的内容永远不会被"执行".你只会得到一个很大的错误,参数值在某种程度上是无效的.

  • 如果您尝试在 SQL(和本例中的 TSQL)不支持变量的地方使用变量,您也会收到错误消息。IE:`FROM` 子句,表示`IN` 子句中逗号分隔列表的单个参数等。 (2认同)
  • 我不认为这回答了问题。您可以使用 SQLParameter 类调用存储过程,该类将参数传递给该过程,但不调用 sp_executesql。连接的 sql 字符串中的参数值会发生什么情况? (2认同)

ana*_*aik 50

一个更容易理解,更通用的答案是这样的:

想象一下动态SQL查询:

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

一个简单的SQL注入就是将Username放入as ' OR 1=1--

这将有效地使SQL查询:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

这表示选择所有用户名为空('')或者1=1布尔值等于true的客户.然后它--用于注释掉查询的其余部分.因此,这将打印出整个客户表,或使您能够随心所欲地执行任何操作.

现在,参数化查询的执行方式不同,代码如下:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)

其中用户名和密码是指向关联的输入用户名和密码的变量.

现在,你可能会想,这根本不会改变任何东西.当然你仍然可以在用户名字段中输入类似Nobody OR 1 = 1'的内容,从而有效地进行查询:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

这似乎是一个有效的论点.但是,你错了.

参数化查询的工作方式是,SQL查询作为查询发送,数据库确切知道此查询将执行的操作,然后才会将用户名和密码仅作为值插入.这意味着它们不会影响查询,因为数据库已经知道查询将执行的操作.所以在这种情况下,它会查找用户名Nobody OR 1=1'--和空密码,这应该是错误的.

这不是一个完整的解决方案,并且仍然需要完成输入验证,因为这不会影响其他问题,例如攻击,因为您仍然可以将javascript放入数据库.然后,如果这被读出到页面上,它将显示为普通的javascript,具体取决于任何输出验证.所以最好的办法仍然是使用输入验证,但使用参数化查询或存储过程来阻止任何SQL攻击.

资料来源:http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html

  • 喜欢你解释的方式:-)清洁和重点. (3认同)

Dav*_*ace 10

"参数集合(如SqlParameterCollection)提供类型检查和长度验证.如果使用参数集合,则输入被视为文字值,SQL Server不会将其视为可执行代码.使用参数集合的另一个好处是您可以强制执行类型和长度检查.超出范围的值会触发异常.这是深度防御的一个很好的例子."

http://msdn.microsoft.com/en-us/library/ff648339.aspx


Mat*_*tin 5

使用参数化查询时,攻击面将减少为使用参数进行修改.

使用SqlParameters,但不要忘记溢出,下溢和未经验证的参数.例如,如果方法是"proc buy_book (@price money)",则恶意攻击者会尝试欺骗应用程序以@priceset to 运行0.01,或者尝试通过提交导致溢出的内容来让应用程序执行一些有趣的操作.Sql溢出往往不是很有趣(即它们只是导致异常,你不太可能写入相邻的内存)