Pregunta

Fondo

Me contrataron para analizar un proveedor de datos existente y sé que el siguiente código es defectuoso; pero para señalar lo malo que es, debo demostrar que es susceptible a la inyección de SQL.

Pregunta

Qué " Clave " parámetro podría interrumpir la función PrepareString y permitirme ejecutar una declaración de DROP ?

Fragmento de código

Public Shared Function GetRecord(ByVal Key As String) As Record
    Dim Sql As New StringBuilder()

    With Sql
        .Append("SELECT * FROM TableName")
        If String.IsNullOrEmpty(Agency) Then
            .Append(" ORDER BY DateAdded")
        Else
            .Append(" WHERE Key = '")
            .Append(PrepareString(Key))
            .Append("'")
        End If
    End With

    Return ExecuteQuery(Sql.ToString())
End Function

Public Shared Function PrepareString(ByVal Value As String) As String
    Return Value.Replace("''", "'") _
                .Replace("'", "''") _
                .Replace("`", "''") _
                .Replace("´", "''") _
                .Replace("--", "")
End Function
¿Fue útil?

Solución

En respuesta a su pregunta directa: ¿Este código impide la inyección de SQL: No

Aquí está la prueba: introduzca esta cadena a través del método PrepareString:

Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-"
Dim output = PrepareString(input)

Console.WriteLine(input)
Console.WriteLine(output)

He modificado el método GetRecord que publicaste para devolver la cadena SQL completamente preparada en lugar de obtener el registro de la base de datos:

Console.WriteLine(GetRecord(output))

Y esta es la salida

Input  = ; Drop Table TableName; --
Output = '; Drop Table TableName; --
Query  = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --'

Agregue 1 línea adicional de código:

My.Computer.Clipboard.SetText(input)

Y tienes la cadena que necesitas copia directamente en tu portapapeles para pegarla en el campo de entrada en el sitio web para completar tu inyección SQL:

'; Drop Table TableName; - -

[Observando que StackOverflow ha omitido los caracteres de control de la salida posterior, por lo que deberá seguir el ejemplo del código para crear su salida]

Después de ejecutar el método PrepareString, tendrá exactamente el mismo resultado: el código ASCII de Chr (8) es el retroceso que eliminará el " '" que estás agregando a la mía, lo que cerrará tu cadena y luego puedo agregar lo que quiera al final. Tu PrepareString no ve mi, porque en realidad estoy usando, con un carácter de retroceso para eliminar el espacio.

El código SQL resultante que estás creando ejecutará mi declaración de Drop Table sin obstáculos e ignorará rápidamente el resto de tu consulta.

Lo divertido de esto es que puedes usar caracteres no imprimibles para básicamente evitar cualquier comprobación de caracteres que puedas inventar. Por lo tanto, es más seguro usar consultas parametrizadas (que no es lo que pidió, pero es el mejor camino para evitar esto).

Otros consejos

Para responder a tu pregunta cuestionable, no funcionaría.

.Replace (" `` " ;, " '' ") evitaría consultas legítimas con '`'

.Replace (" & # 180; " ;, " '' ") evitaría consultas legítimas con '& # 180;'

.Replace (" - " ;, " " ") evitaría consultas legítimas con '-' en ellas

.Replace (" '' " ;, " '") modificaría incorrectamente las consultas legítimas con' '' 'en ellas

y así sucesivamente.

Además, el conjunto completo de caracteres de escape puede variar de un RDBMS a otro. Consultas parametrizadas FTW.

Creo que es inaccesible si simplemente reemplaza 'por' '. He escuchado que es posible cambiar el carácter de cita de escape, lo que potencialmente podría romper esto, pero no estoy seguro. Aunque creo que estás a salvo.

Creo que es seguro (al menos en el servidor SQL), y también creo que lo único que necesitas hacer es s = s.Replace (" '" ;, "' '") . Por supuesto, debe utilizar consultas parametrizadas, pero eso ya lo sabe.

Este artículo de MSDN cubre la mayoría de las cosas que necesita Esté atento (tengo miedo de decirlo todo cuando se trata de inyección SQL).

Pero me haré eco de la opinión de todos los demás parámetros parámetros parámetros parámetros.

En cuanto a su ejemplo, algunos errores [Editar: Actualizado estos]:

  • no sería la cadena " 1 OR 1 = 1 " permitir al usuario recuperar todo

  • o peor " 1; drop table sometablename "

De acuerdo con el artículo que desea verificar:

  

; - Consulta delimitador.

     

'- Delimitador de cadena de datos de caracteres.

     

- - Delimitador de comentarios.

     

/ * ... / - Delimitadores de comentarios. Texto   entre / y * / no es evaluado por   el servidor.

     

xp_ - Se usa al comienzo del nombre de   procedimientos almacenados extendidos por catálogo,   como xp_cmdshell.

Está intentando incluir en una lista negra de caracteres para implementar su propia versión de SQL Escaping. Sugeriría revisar esta URL . Escapar de SQL no es necesariamente la peor opción (es decir, rápidamente arreglando las aplicaciones existentes) pero debe hacerse correctamente para evitar vulnerabilidades.

Esa URL enlaza con otra página para escapar en SQL Server donde el autor ofrece sugerencias que lo ayudan a evitar vulnerabilidades sin limitar la funcionalidad.

Si ayuda, los artículos también sugieren que se escapen llaves (los llamo corchetes, pero []).

Si intentas usar tu código, alguien podría pasar una clave (; select * from table; y obtener una lista de la tabla que quiera.

En tu código no estás buscando el punto y coma, lo que te permite finalizar una instrucción t-sql y comenzar otra.

Iría con una consulta parametrizada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top