2009-12-02 16 views
6

Estoy intentando simplemente demostrar aquí que esta función simple no es lo suficientemente bueno para prevenir cada inyección SQL en el mundo:prueban que pueden inyección SQL

Function CleanForSQL(ByVal input As String) As String 
    Return input.Replace("'", "''") 
End Function 

Aquí está una instrucción de inserción típica de una de nuestras aplicaciones :

Database.DBUpdate("UPDATE tblFilledForms SET Text1 = '" + CleanForSQL(txtNote.Text) + "' WHERE FilledFormID = " + DGVNotes.SelectedRows(0).Cells("FilledFormID").Value.ToString) 

sé que no es seguro, debido a google y buscar otras preguntas sobre StackOverflow.com. Here es una pregunta que encontré en la que todas las funciones como la que presenté anteriormente son irrelevantes e inútiles.

Así que basado en el post que está conectado, simplemente escribiendo

'Chr (8); actualizar tblMaint SET Valor1 = 2 DONDE ValueID = 2--

en txtNote debería ser suficiente para borrar todos los valores de texto1 en toda la tabla tblFilledForms, y luego actualizar segunda fila de la tabla tblmaint sea correcta 2?

lo que debería ocurrir aquí es que VB lo interpretará como

tblFilledForms actualización del conjunto Text1 = '' 'Chr (8); actualizar tblMaint SET Valor1 = 2 DONDE ValueID = 2-- 'DONDE FilledFormID = 5120327

y enviarlo a SQL que se ejecute el pasante Chr (8) para borrar la tercera' que produciría

ACTUALIZACIÓN tblFilledForms SET Text1 = ''; update tblMaint SET Value1 = 2 WHERE ValueID = 2-- 'WHERE FilledFormID = 5120327

para ser realmente ejecutados en la base de datos correcta?

Luego coppied un Chr (8) desde el portapapeles y reemplacé el Chr (8) en el cuadro de texto con el contenido del portapapeles y todavía no lo hago. Pone toda la cadena directamente en el campo sin problemas.

Entonces, ¿qué estoy haciendo mal aquí? o ¿qué más puedo hacer para romperlo?

Tecnologías y fondo: estoy usando MS SQL Server 2005 y Visual Basic .NET 2005. el campo Texto1 en la base de datos es una (600) campo varchar (no pregunte por qué no mi su MAX, es inútil, lo sé) Hay ciertos factores desencadenantes en la tabla que evitarían una actualización masiva como esta y arrojarían algunos errores si la inyección funcionó correctamente.

PS. Sé que las consultas parametrizadas son el camino a seguir aquí y no estoy buscando respuestas como "bueno, no sé por qué no funciona, pero las consultas parametrizadas son el camino a seguir". Estoy buscando la capacidad de demostrar que nuestro software está roto y que tenemos que reescribirlo utilizando mejores principios.

Para cualquiera que lea esta pregunta y descubra cómo filtrar mejor los campos de texto, ¡la respuesta es NO! Use los parámetros! ¡son mucho mejores, más seguros y más fáciles!

+5

Voto a favor de personas amenazantes y redactores principales en lugar de principios en el mismo párrafo. –

+0

Bueno, tu Chr (8) termina dentro de una cadena, por eso SQL no lo está evaluando. –

+6

@Vinko No creo que eso sea justo, simplemente estaba estableciendo una pauta de respuestas.Entonces, en lugar de obtener un montón de respuestas diciendo lo mismo, obtiene 1 o 2 que le dicen lo que quiere. – Zoidberg

Respuesta

6

El Chr (8) es parte de la cadena literal entre comillas, al igual que la instrucción de actualización, por lo que SQL Server no lo va a interpretar como una llamada a función. Con este ejemplo, Texto1 se establecerá en el valor literal:

'Chr(8); update tblMaint SET Value1 = 2 WHERE ValueID = 2-- 

(sí, incluyendo la comilla simple)

Así pues, con este ejemplo, el código de es seguro. La mayoría de los errores de escritura sobre SQL se deben a que falla para validar y citar valores, no hay nada intrínsecamente inseguro en una declaración de SQL correctamente citada.

+0

ha hecho +1 porque tu respuesta puede estar siendo la última respuesta para esta pregunta. – Jrud

0

Creo que su problema es que Chr(8) no se ejecuta, es necesario encontrar otra manera de conseguir la marca líder en el presupuesto.

+0

sí, lo hago ... ¿alguna sugerencia? – Jrud

1

No estás haciendo nada malo. Así es como SQL Server analiza cadenas. La primera cita abre la cadena, luego has seguido eso inmediatamente con una comilla escapada seguida de Chr (8).

Como ejercicio, ¿qué ocurre si ejecuta esto en SQL Server: SELECT '''Hello'? Exactamente las mismas reglas de análisis se están aplicando en este caso.

+0

sí, eso es exactamente lo que está pasando, lo entiendo. Pero aún necesito romperlo de alguna manera ... – Jrud

+0

No es necesario que lo rompa, solo necesita probar que su técnica funciona para todos los casos, o no. –

+0

sí, si funciona para todos los casos, eso lo desaprueba por eliminación. – Jrud

4

Su método CleanForSQL solo maneja situaciones de cadenas. ¿Qué sucede cuando no estás usando una cadena sino una INT en su lugar? En ese caso, no habría un tic de final para cerrar, por lo que la inyección seguiría ocurriendo. Considere este ejemplo ...

Database.DBUpdate("UPDATE tblFilledForms SET Int1 = " + CleanForSQL(txtNote.Text) + " WHERE FilledFormID = " + DGVNotes.SelectedRows(0).Cells("FilledFormID").Value.ToString) 

en ese caso, acaba de entrar en la siguiente funcionará ...

0; update tblMaint SET Value1 = 2 WHERE ValueID = 2--

+0

No permitimos que los usuarios escriban ningún número en campos de texto que primero no se verifiquen por ser numéricos. Estoy seguro de que esto se rompería si fuera un campo numérico, pero no usamos este método para eso. Es estrictamente para cuerdas. – Jrud

+4

No olvide que podrían ser números de identificación o algo similar en las cadenas de consulta, no solo cuadros de texto. La mayoría de las inyecciones que he encontrado han sido variables sin marcar en la cadena de consulta, y no en campos de formulario. –

+2

+1 a cadenas de consulta - Y no olvide que cualquiera puede crear un formulario falso para publicar en su página. No sé cómo se está estableciendo DGVNotes.SelectedRows (0) .Cells ("FilledFormID"), pero si proviene del navegador TODO, se puede inyectar SQL. Sé que siempre revisas tus campos numéricos, pero si alguna vez lo olvidas, se abre un agujero. –

3

de Scott Ivey tiene el caso clásico que puede romperlo, la falta de cotizaciones proteger una entrada numérica. (Ha hecho +1 en eso)

Dependiendo del idioma y de dónde se "limpia" la cadena y de la base de datos que se utiliza, su riesgo inmediato es que el lenguaje permita que se escape la cadena. En ese punto, la cita simple que está tratando de evitar se saldrá mal

\ '; DROP yourTable; - => \ ''; DROP YourTable; -

que entra en su cadena SQL como

UPDATE tblFilledForms SET Text1 = '" + \''; DROP yourTable;-- + ' etc. 

Cuál es entonces:

UPDATE tblFilledForms SET Text1 = '\''; DROP yourTable;-- ' etc. 

'\'' se toma como la cadena literal de una única oferta, si su base de datos admite caracteres escapados: el bingo está comprometido.

Igualmente debe recordarse que la protección es efectiva, incluso la instrucción de actualización de ejemplo provista no protegió el parámetro en la cláusula where, fue porque DGVNotes.SelectedRows (0) .Cells ("FilledFormID"). Valor. ToString) nunca podría ser ingresado por un usuario? ¿Será eso cierto durante toda la vida de la aplicación, etc.?

+0

Probablemente solo la tecnología de DB que estoy usando ... MS SQL Server ve '' para significar que realmente quería escribir \ 'no es un carácter literal o de escape. Para SQL Server, dos comillas simples juntas se interpretan como una comilla simple literal que hace que cualquier '' que se pasa a él sea literal 'dentro de la cadena y no se ejecutará. – Jrud

+0

Sí, SQL solo escapa de ciertas cosas y usa [como el escape, MySQL usa \ Creo que así se encuentra con este problema. – Andrew