ASP Classic - Recordset对象与命令对象

时间:2010-08-06 14:31:36

标签: stored-procedures asp-classic sql-server-2000 sql-injection

我使用ASP Classic和SQL Server 2000来创建动态网站。

我对何时使用记录集对象以及何时在查询数据库时使用命令对象感到困惑。

我被告知如果存储过程将从SELCT语句返回记录,那么我应该使用记录集,但是如果我更新或插入,那么我应该使用命令对象并将所有数据作为参数传递给存储过程

使用记录集时,我经常传递任何所需的数据,如下所示:

rs.Source = "spTest "   & id

我总是验证我传递的数据,以确保它是我期待的并将其转换为正确的类型。

我被告知,上面的方法让我的代码对SQL注入攻击开放,我应该总是使用命令对象。

这是对的吗?

由于

2 个答案:

答案 0 :(得分:3)

是的,没错。

想象一下有人传递字符串:'0;从用户删除*;'

您的查询将是:

spTest 0; delete * from users;

如果你很幸运,你将没有用户表。就个人而言,我会一直使用命令对象来保持一致性。您可以从中获得所需的一切。

以下是如何使用命令对象执行此操作的快速示例:

    Dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")

    With oStoredProc
        .ActiveConnection = oDBConnection
        .CommandType = adCmdStoredProc
        .CommandText = "up_procname"
        .Parameters.Append(.CreateParameter("@Param1", ADODB.adInteger, ADODB.adParamInput, 22, 11))
        .Parameters.Append(.CreateParameter("@Param2", ADODB.adInteger, ADODB.adParamOutput, 22, 12)

        Call .Execute()

        myVal = .Parameters("@Param2")
    End With

    Set oStoredProc = Nothing

答案 1 :(得分:1)

你被告知的确是正确的:你应该总是使用commande对象来阻止SQL注入。使用参数化查询,您可以将所有参数的安全性和验证保留在ADO层中(尽管您仍应进行适当的验证),甚至可以获得一些性能改进(这些参数化查询由SQL Server缓存)

当你执行命令时,你有两个选择:你执行的SQL返回行(一个SELECT语句,或一些存储过程),然后你必须使用记录集来存储这些行,否则它不会(更新) ,删除,其他程序),然后你执行命令,不要担心记录集。

编辑:为了确保一切都清楚,我使用上面的James Wiseman的代码并根据你的例子进行调整:

Dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")

With oStoredProc
    .ActiveConnection = oDBConnection
    .CommandType = adCmdStoredProc
    .CommandText = "spTest ?"
    .Parameters.Append(.CreateParameter("id", ADODB.adInteger, ADODB.adParamInput, id, 11))
    Dim rs : Set rs = .Execute()
End With

Set oStoredProc = Nothing

没有测试,但应该没问题: - )

最后但并非最不重要:即使你现在受到很好的保护,也不要忘记,如果你在存储过程中使用动态SQL,你可能仍然有一个SQL注入安全漏洞(只要你是连接字符串来创建SQL你可能会说我很容易受到攻击!)