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

标签 sql vb.net prepared-statement

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

相关文章:

php - 使用准备好的语句从 PHP5 中的 MySQL 存储过程获取结果

sql - 用户拥有数据库固定角色意味着什么?

php - 如何在 php 中为数据库中选定的表创建 sql 日志?

c# - 加密 web.config 部分

java - 借助枚举 VB.NET 获取设置

prepared-statement - Couchbase 的准备语句的正确语法是什么?

mysql - 员工参与所有服务

mysql - 合并两列并按 asc 排序

vb.net - DateTimePicker 的 MonthCalendar 的日期未更新

c# - Sql Server LIKE 查询中需要转义哪些字符