执行从参数字符串连接的脚本时如何防止 SQL 注入?

Posted

技术标签:

【中文标题】执行从参数字符串连接的脚本时如何防止 SQL 注入?【英文标题】:How to prevent SQL Injection when executing the script concatenated from parameter strings? 【发布时间】:2016-06-12 04:14:03 【问题描述】:

作为同一个主题,我想在执行以下sql命令时防止SQL注入:

Dim strSQL As String = "ALTER TABLE " & tablename & " ADD " & fieldName & " " & datatype
_db.Execute_NonQuery(strSQL)

我尝试应用参数化http://software-security.sans.org/developer-how-to/fix-sql-injection-microsoft-.net-with-parameterized-queries 的解决方案,但我仍然收到此消息

类别的名称。

值:SQL 中使用的特殊元素的不正确中和 命令('SQL 注入')

描述:对缺陷类型的更详细描述。

值:此数据库查询包含 SQL 注入缺陷。通话 到 system_data_dll.System.Data.IDbCommand.ExecuteNonQuery() 构造 使用从用户提供的输入派生的变量的动态 SQL 查询。 攻击者可以利用此漏洞执行任意 SQL 查询 针对数据库。 ExecuteNonQuery() 在一个对象上被调用,它 包含受污染的数据。受污染的数据源自早期的调用 到 system_data_dll.system.data.sqlclient.sqlcommand.executescalar,和 system_data_dll.system.data.common.dbdataadapter.fill。避免 动态构造 SQL 查询。相反,使用参数化 准备好的语句以防止数据库解释 绑定变量的内容作为查询的一部分。始终验证 用户提供的输入,以确保它符合预期的格式, 尽可能使用集中的数据验证程序。参考: CWE (http://cwe.mitre.org/data/definitions/89.html) OWASP (http://www.owasp.org/index.php/SQL_injection) (http://webappsec.pbworks.com/SQL-Injection)

更新

原码:

Public Shared Sub AlterTable(ByVal table As String, ByVal fieldName As String, ByVal fieldType As String)

    Dim strSQL As String = "ALTER TABLE " & PROJ & fileCode & " ALTER COLUMN " & fieldName & " " & fieldType
    _db.Execute_NonQuery(strSQL)

End Sub

Public Overloads Function Execute_NonQuery(ByVal sql As String) As Integer
    Dim result As Integer = 0

    Try
        Using conn As New SqlConnection(connString)
            conn.Open()
            If conn IsNot Nothing Then
                Using myTrans As SqlTransaction = conn.BeginTransaction()
                    Using oCmd As SqlCommand = New CommonDao().GetCommand(conn, sql, CommandType.Text)
                        If (oCmd IsNot Nothing) Then
                            oCmd.Transaction = myTrans

                            result = oCmd.ExecuteNonQuery()
                            myTrans.Commit()
                        End If
                    End Using
                End Using
            End If
        End Using
    Catch ex As Exception
        _logger.Error("SQL: " & sql)
        _logger.Error("Error: " & ex.Message)
        Throw ex
    End Try
    Return result
End Function

我修改后的代码

Public Shared Sub AlterTable(ByVal table As String, ByVal fieldName As String, ByVal fieldType As String)

    Dim strSQL As String = "ALTER TABLE @table ALTER COLUMN @fieldName @fieldType"
    _db.Execute_NonQuery(strSQL, New String() "@table","@fieldName","@fieldType", New Object() table, fieldName, fieldType, False, CommandType.Text)

End Sub

Public Overloads Function Execute_NonQuery(ByVal spName As String, ByVal param() As String, ByVal values() As Object, ByVal orderNum As Boolean, ByVal commandType As CommandType) As Integer
    Dim result As Integer = 0

    Try
        Using conn As New SqlConnection(connString)
            conn.Open()
            If conn IsNot Nothing Then
                Using oCmd As SqlCommand = New CommonDAO().GetCommand(conn, spName, commandType)
                    If (oCmd IsNot Nothing) Then
                        If Not (param Is Nothing) AndAlso (param.Length > 0) Then
                            For i = 0 To param.Length - 1
                                oCmd.Parameters.Add(New SqlParameter(param(i), values(i)))
                            Next
                        End If

                        result = oCmd.ExecuteNonQuery()
                    End If
                End Using
            End If
        End Using
    Catch ex As Exception
        _logger.Error("SQL: " & spName)
        _logger.Error("Error: " & ex.Message)

        Throw ex
    End Try

    Return result
End Function

【问题讨论】:

您所做的修复是什么样的? 你应该添加你现在拥有的代码。 @guys,我已经更新了问题的原代码和修改代码 我不确定这会创建有效的 SQL,这种方法应该在您的输入周围加上单引号,因为它们是字符串,例如:ALTER TABLE 'tablename' ADD 'fieldname' 'VARCHAR(50)',这是无效的 SQL。 你是对的,Jaco。我确实选择了错误的解决方案:W 【参考方案1】:

根据用户输入动态更改表格是一种非常奇怪的方法。我几乎可以肯定你在这里做错了什么。

您需要添加一列还是只需要使用另一个表和一些连接重新设计您的数据库?

话虽如此,您可能可以通过将动态 SQL 推入存储过程并执行它来隐藏问题。这不好,但是如果您只是响应警告并且无法从不受信任的来源执行此代码,则它可能是最实用的。

我可以通过快速谷歌找到最接近的是:

https://technet.microsoft.com/en-us/library/ms162203(v=sql.90).aspx

这是VB,但我相信你可以解决。

【讨论】:

以上是关于执行从参数字符串连接的脚本时如何防止 SQL 注入?的主要内容,如果未能解决你的问题,请参考以下文章

ASP程序防止SQL注入的最好办法?

mybatis为何能防止sql注入

FromSql():从字符串列表构建查询字符串以防止注入

如何实现php的安全最大化?怎样避免sql注入漏洞和xss跨站脚本攻击漏洞

pg数据库like防止sql注入

从搜索表单动态构建 WHERE 子句时如何防止 SQL 注入?