我听说“每个人”都在使用参数化 SQL 查询来防止 SQL 注入(inject)攻击,而无需验证每一条用户输入。
你是如何做到这一点的?使用存储过程时会自动获取此信息吗?
所以我的理解这是非参数化的:
cmdText = String.Format("SELECT foo FROM bar WHERE baz = '{0}'", fuz)
这会被参数化吗?
cmdText = String.Format("EXEC foo_from_baz '{0}'", fuz)
或者我是否需要做一些像这样更广泛的事情来保护自己免受 SQL 注入(inject)?
With command
.Parameters.Count = 1
.Parameters.Item(0).ParameterName = "@baz"
.Parameters.Item(0).Value = fuz
End With
除了安全考虑之外,使用参数化查询还有其他优点吗?
更新:这篇精彩的文章链接在 Grotok 的一个问题引用文献中。 http://www.sommarskog.se/dynamic_sql.html
最佳答案
问题中的 EXEC
示例不会被参数化。您需要参数化查询(在某些圈子中是准备好的语句)来防止这样的输入造成损坏:
';DROP TABLE bar;--
尝试将其放入您的 fuz
变量中(或者如果您重视 bar
表,则不这样做)。更微妙和更具破坏性的查询也是可能的。
以下是如何使用 Sql Server 执行参数的示例:
Public Function GetBarFooByBaz(ByVal Baz As String) As String
Dim sql As String = "SELECT foo FROM bar WHERE baz= @Baz"
Using cn As New SqlConnection("Your connection string here"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("@Baz", SqlDbType.VarChar, 50).Value = Baz
Return cmd.ExecuteScalar().ToString()
End Using
End Function
存储过程有时被认为可以防止 SQL 注入(inject)。但是,大多数时候您仍然必须使用查询参数来调用它们,否则它们没有帮助。如果您独占使用存储过程,那么您可以关闭应用程序用户帐户的 SELECT、UPDATE、ALTER、CREATE、DELETE 等权限(几乎除了 EXEC 之外的所有权限),并通过这种方式获得一些保护.
关于sql - 如何创建参数化 SQL 查询?我为什么要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/542510/