4

Я использую ASP Classic и SQL Server 2000 для создания динамических веб-сайтов.ASP Classic - Объект Recordset и объект Command

Я немного смущен, когда следует использовать объект recordset и когда использовать объект команды при запросе базы данных.

Мне сказали, что если хранимая процедура будет возвращать записи из инструкции SELCT, тогда я должен использовать набор записей, однако, если я обновляю или вставляю, я должен использовать объект команды и передавать все данные в качестве параметров в хранимая процедура.

При использовании записей я часто передавать все необходимые данные, как так:

rs.Source = "spTest " & id 

Я все дни проверки достоверности данных, которые я передаю, чтобы убедиться, что это то, что я ожидал и бросить его в правильный тип.

С тех пор мне сообщили, что указанный выше метод оставляет мой код открытым для атак SQL Injection и что я всегда должен использовать объект команды.

Это правильно?

Thanks

ответ

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 
+0

Спасибо. Скажите, что, как и в примере, который я дал, я знаю, что параметр будет числовым, и я проверил вход, чтобы убедиться, что он есть. Было бы хорошо использовать объект набора записей, как я описал, или я должен использовать объект команды независимо? Я только спрашиваю, как много времени, это только числовые значения, которые я прохожу, и это спасло бы меня много времени, если бы мне не пришлось пройти и изменить их все. Thanks – chester600

1

То, что вы сказали правильно, действительно: вы всегда должны использовать COMMANDE объекты для предотвращения SQL Injection. Используя параметризованные запросы, вы оставляете всю безопасность и проверку параметров на уровне ADO (хотя вы все равно должны сделать свою собственную правильную проверку), и вы даже можете добиться некоторого повышения производительности (эти параметризованные запросы кэшируются SQL Server)

Когда вы выполняете команду, у вас есть два варианта: либо SQL, который вы выполняете, возвращает строки (инструкция SELECT, либо некоторые хранимые процедуры), тогда вам нужно использовать набор записей для хранения этих строк, либо нет (UPDATES, DELETES , другие процедуры), то вы просто выполните команду и не беспокойтесь о наборах записей.

Edit: просто чтобы убедиться, что все это ясно для вас, я использовал код Джеймса Уайзман выше и адаптировать его к примеру:

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 Injection (как только вы конкатенируя строки для создания SQL, вы можете быть уязвимы, я бы сказал)!

+0

Спасибо. Так должен ли я когда-либо использовать объект recordset вместе с командой obbject? Я также предполагаю, что это нормально, если я использую объект набора записей, когда я запускаю хранимую процедуру, которая не требует передачи каких-либо параметров? Thanks – chester600

+0

Чтобы упростить задачу, я бы посоветовал вам всегда использовать один и тот же метод: просто используйте Recordsets с объектами Command и больше не думайте об этом. У вас может быть немного больше времени для ввода, но это можно легко избежать с помощью некоторых вспомогательных функций, которые вы можете написать (вы скоро увидите, какой код всегда повторяется) –

Смежные вопросы