小编典典

如何创建参数化的SQL查询?我为什么要?

sql

我听说“每个人”都在使用参数化的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


阅读 159

收藏
2021-05-05

共1个答案

小编典典

您的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之外,几乎所有其他权限),并以此方式获得一些保护。

2021-05-05