我听说“每个人”都在使用参数化的SQL查询来防止SQL注入攻击,而不必验证用户的每一项输入。
你怎么做到这一点?使用存储过程时,是否会自动获得此信息?
所以我的理解是非参数化的:
cmdText = String.Format("SELECT foo FROM bar WHERE baz = '{0}'", fuz)
可以将其参数化吗?
cmdText = String.Format("EXEC foo_from_baz '{0}'", fuz)
还是我需要像这样做一些更广泛的事情,以保护自己免受SQL注入的侵害?
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栏;-
尝试将其放在您的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注入。但是,大多数时候您仍然必须使用查询参数来调用它们,否则它们将无济于事。如果 仅 使用存储过程,则可以关闭应用程序用户帐户的SELECT,UPDATE,ALTER,CREATE,DELETE等权限(除了EXEC之外,几乎所有其他权限),并以此方式获得一些保护。