¿Cómo vencer la duplicación de apóstrofes para crear un ataque SQLi?

17

Sé que algunos desarrolladores duplican apóstrofes para mitigar SQLi. (Esto es cuando la entrada es 'por lo que se convierte en' ')

¿Hay alguna manera de superar esto?

Esto está en el servidor MS SQl.

    
pregunta DomBat 18.12.2015 - 10:35
fuente

3 respuestas

36

Intento mostrar ambos lados del espectro de seguridad. La seguridad es importante, por lo que no solo debes saber cómo anular la seguridad, también debes saber cómo implementarla. Por lo tanto, voy a enumerar una prevención primero. Si no quieres leer esto, desplázate hacia abajo.

¿Cómo impido la inyección de SQL?

Duplicar apóstrofes no es no la respuesta cuando se trata de seguridad, y puede llevar a la inseguridad. La respuesta depende del lenguaje de programación que estés usando.

  • Para SQL Server / Oracle / MySQL
    • Con Java, use CallableStatements y PreparedStatements correctamente.
    • Con PHP, necesitará las declaraciones preparadas apropiadas.
    • Con C # / VB.NET, necesitarás consultas parametrizadas.

Tenga en cuenta que estos son todos los mismos conceptos en todos los idiomas. Solo tienen nombres diferentes.

Incluso con declaraciones preparadas / invocables o consultas parametrizadas, lo siguiente es incorrecto:

// Bad code, don't use 
string sqlString = "SELECT * FROM [table] WHERE [col] = '"+ something +"' AND [col2] = @Param";

Usted debe nunca concatenar sus variables SQL.

Con el servidor SQL, dependiendo de la lengua elegida de su elección, su consulta debería tener este aspecto:

  • C #

    using (SqlCommand command = new ("SELECT * FROM [tab] WHERE LName = @LName", connection))
    {
        // Add new SqlParameter to the command.
        command.Parameters.Add(new SqlParameter("LName", txtBox.Test));
    
        // Read in the SELECT results.
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        {
        }
    }
    
  • Java

    Connection con = DriverManager.getConnection("database-connection-string","name","pass");
    
    // Question marks are the bound variables which are parsed in the defined column order. 
    PreparedStatement findLName = con.prepareStatement("SELECT * FROM [tab] WHERE LName = ?");
    
    // The order in which the question marks appear. You can have more than one in a prepared statement. First one is "1", second is "2", and so on.
    findLName.setString(1, Lastname);
    
    findLName.executeQuery();
    
    Statement stmt = con.createStatement();
    
  • PHP

    Revise w3schools para ver un ejemplo, no quiero que mi respuesta se alargue demasiado.

Tenga en cuenta que esto todavía no elimina la inyección potencial de scripts en una página web. Puede insertar exactamente lo que piden, dentro de los rangos aceptables y luego enviar los resultados a HTML.

Si insertan lo siguiente (ejemplo simplificado):

<script> window.location.href='hxxp://www.mymalwarewebsite.com/'; </script>

... y envías ese resultado a tu página, entonces estás en un gran problema. Entonces, ¿qué pasa si eliminas algo de <script> a </script> ? ¿Qué pasa si se insertan:

<scri<script>pt> window.location.href='hxxp://www.mymalwarewebsite.com/'; </scri<script>pt>

...? Si elimina las etiquetas de secuencia de comandos con reemplazar, todavía está atascado con esa vulnerabilidad.

Lo que realmente quiere es lo siguiente además de lo anterior :

¡Cállate, Mark! ¿Cómo puedo superar la duplicación de apóstrofes?

  • Es posible que puedas vencerlos en formas diferentes ; es posible que pueda forzar que varias bases de datos SQL traduzcan unicode al conjunto de caracteres local . Por ejemplo, Ā podría convertirse a A . Peor aún: U+02BC , o ʼ se traduciría como ' , que es U+0027 . Esto se llama Contrabando basado en Unicode .
    • citas de duplicación no funciona en versiones anteriores de MySQL.
  • Aunque no es realmente un ataque de inyección de SQL, puede intentar forzar al sitio web a que inyecte un código malicioso para mostrarlo a sus usuarios. Puede intentar insertar etiquetas de script (lea más arriba para ver un ejemplo). Imagine inyectar una descarga en automóvil cuando la gente vea su página o una lista de usuarios.
  • Aunque técnicamente no es un ataque de inyección de SQL, es posible que pueda superar esta protección mirando a través de la consola en su navegador y verificando los enteros que se envían a la base de datos, y luego modifique la solicitud. Esto se denomina una vulnerabilidad Referencia de objeto directo . Existen varias herramientas que pueden hacer esto. Las declaraciones preparadas no lo protegerán contra este ataque. Por favor lea el artículo de OWASP
respondido por el Mark Buffalo 18.12.2015 - 14:35
fuente
13
  

¿Hay alguna manera de superar esto?

Quizás (al menos con MySQL). Y es realmente simple (no necesita ninguna codificación especial ni la ausencia de comillas, ni nada):

\' [injection] -- -

Entonces, por ejemplo, tienes esta consulta:

SELECT FROM table WHERE user = '[INPUT]';

La entrada es \' [injection] -- - , pero con ' duplicado, se convierte en: \'' [injection] -- - , lo que nos lleva a esta consulta:

SELECT FROM table WHERE user = '\'' [injection] -- -';

La parte inyectada se ejecutará como una consulta, ya que ya no está dentro de las comillas.

La única defensa adecuada contra la inyección de SQL son las declaraciones preparadas. Tampoco son difíciles de usar y, a menudo, dan como resultado un código más agradable. Realmente no hay una buena excusa para las defensas caseras, como doblar las cotizaciones.

// actualización: parece que esto no sería posible con MSSQL. Así que eso dejaría los dos problemas ya mencionados en las otras respuestas: aún es vulnerable si no se utilizan comillas en la consulta , o (posiblemente) para ciertos conjuntos de caracteres.

También depende de cómo se produzca realmente la duplicación. Si se hace, por ejemplo, a través de la base de datos , puede ser vulnerable. .

    
respondido por el tim 18.12.2015 - 15:18
fuente
7

Esto solo evita los ataques de inyección SQL a través de parámetros de cadena. A veces, el parámetro es un entero (piense http://www.example.org/?page=3 ), entonces no necesita un apóstrofe. A veces, puede comprobar si los parámetros son vulnerables si reemplaza page=3 con page=1+2 , por ejemplo.

    
respondido por el Volker 18.12.2015 - 13:52
fuente

Lea otras preguntas en las etiquetas