stored-procedures asp-classic sql-server-2000 sql-injection

stored procedures - ASP Classic-objeto Recordset frente a objeto Command



stored-procedures asp-classic (2)

Estoy usando ASP Classic y SQL Server 2000 para crear sitios web dinámicos.

Estoy un poco confundido acerca de cuándo usar un objeto recordset y cuándo usar un objeto command al consultar la base de datos.

Me dijeron que si el procedimiento almacenado devolvería registros de una instrucción SELCT, entonces debería usar un conjunto de registros; sin embargo, si estoy actualizando o insertando, entonces debería usar un objeto de comando y pasar todos los datos como parámetros al procedimiento almacenado.

Cuando utilizo un conjunto de registros, a menudo paso cualquier información requerida como esta:

rs.Source = "spTest " & id

Siempre valido los datos que estoy aprobando para asegurarme de que es lo que espero y convertirlo al tipo correcto.

Sin embargo, me han dicho que el método anterior deja mi código abierto a los ataques de inyección SQL y que siempre debería usar un objeto de comando.

¿Es esto correcto?

Gracias


Lo que le dijeron es correcto: siempre debe usar objetos commande para evitar la inyección de SQL. Usando consultas parametrizadas, dejas toda la seguridad y validación de parámetros en la capa ADO (aunque aún debes hacer tu propia validación), e incluso puedes obtener alguna mejora en el rendimiento (estas consultas parametrizadas son almacenadas en caché por SQL Server)

Cuando ejecuta un comando, tiene dos opciones: o bien el SQL que ejecuta devuelve filas (una instrucción SELECT o algunos procedimientos almacenados), luego tiene que usar un conjunto de registros para almacenar estas filas, o bien no (ACTUALIZACIONES, BORRADORES, otros procedimientos), entonces usted juste ejecutar el comando y no se preocupe por los conjuntos de registros.

Editar: solo para asegurarse de que todo esté claro para usted, utilicé el código de James Wiseman anterior y lo adapté a su ejemplo:

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

No lo probé, pero debería estar bien :-)

Por último, aunque no menos importante: aunque ahora está bastante bien protegido, no olvide que si utiliza SQL dinámico dentro de su procedimiento almacenado, es posible que todavía tenga un agujero de seguridad de inyección SQL (tan pronto como esté concatenando cadenas para crear SQL puede ser vulnerable, diría)!


Si, eso es correcto

Imagina a alguien pasando la cadena: ''0; eliminar * de los usuarios; ''

La consulta sería entonces:

spTest 0; delete * from users;

Si tienes suerte, no tendrás una mesa de usuarios. Personalmente, usaría el objeto de comando todo el tiempo para mantener la coherencia. Puede obtener todo lo que necesita de ella.

Aquí hay un ejemplo rápido de cómo puede hacerlo con el objeto de comando:

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