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.
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.
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.
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 sea demasiado larga.
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 :
HtmlEncode
Java Html Sanitizer from OWASP
HtmlEntities
. Ā
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 .
¿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, resultan en 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. .
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.
Lea otras preguntas en las etiquetas sql-injection