¿Inyección SQL usando letras y números?

8

Me preguntaba si es posible que un hacker realice un ataque de inyección de SQL utilizando solo letras y números. Por ejemplo, echemos un vistazo a este código PHP que usa expresiones regulares en lugar de las funciones incorporadas de PHP:

<?php
$id = preg_replace('/[^a-zA-Z0-9]/', '', $_GET['id']);
$result = $mysqli->query("SELECT * users WHERE id = '".$id."'");

En caso de que se pregunte qué hace el código, elimina todos los caracteres que no son letras o números y ejecuta esa consulta en MySQL. Me preguntaba si un pirata informático podría explotar ese código de alguna manera y, de no ser así, ¿cuál sería la diferencia entre eso y mysqli::prepare o mysqli::escape_string ?

    
pregunta ub3rst4r 04.07.2013 - 05:48
fuente

4 respuestas

8

Solo habría una falla de seguridad si fuera posible dejar la cadena de MySQL contexto literal el valor $id se inserta en y para proporcionar fragmentos de SQL arbitrarios. Y esto solo es posible si $id contiene el plano ' que denotaría el delimitador final del literal de la cadena MySQL:

// resulting SQL statement with $id = "' OR '1'='1"
SELECT * users WHERE id = '' OR '1'='1'

Ahora que está eliminando cualquier carácter ' de $id , no es posible dejar el contexto literal de la cadena y, por lo tanto, no es posible suministrar fragmentos de SQL arbitrarios.

Sin embargo, esta conclusión se aplica solo en el caso de que el valor se utilice en un literal de cadena MySQL. Si está utilizando el mismo filtrado de entrada en los valores de una consulta diferente, todavía puede ser vulnerable a las inyecciones de SQL.

Dicho esto, los métodos como mysqli::prepare y mysqli::escape_string son técnicas de mitigación adecuadas. mysqli::prepare implementa lo que se denomina instrucción / consulta parametrizada a través de sentencias preparadas donde el comando (instrucción SQL) y los datos proporcionados por el usuario están separados unos de otros para que los datos proporcionados por el usuario no puedan interpretarse por error como comando mysqli::escape_string sería similar a su técnica actual, ya que simplemente escapa ciertos caracteres de los datos para no confundirse como control caracteres como el delimitador de final de literal de cadena.

    
respondido por el Gumbo 04.07.2013 - 07:34
fuente
3

(Lo publicaría como un comentario, pero los comentarios no hacen los enlaces correctamente).

Esto es bastante similar a many < a href="https://stackoverflow.com/questions/8506574/sql-injection-isnt-replace-good-enough"> questions en Stack Overflow.

El Proyecto de seguridad de aplicaciones web abiertas (OWASP) nota que Escapar de caracteres especiales es una defensa contra la inyección de SQL:

  
  1. Utilice declaraciones preparadas (consultas parametrizadas) y procedimientos almacenados
  2.   
  3. Si una API parametrizada no está disponible ... Escape Caracteres especiales
  4.   
  5. Realizar la validación de entrada de la lista blanca
  6.   

En cuanto al código de prueba de concepto que logra SQLi sin caracteres especiales, no he visto ninguno, pero la ausencia de evidencia no es evidencia de ausencia. Si puede implementar consultas parametrizadas, ¿por qué no hacerlo?

    
respondido por el scuzzy-delta 04.07.2013 - 06:46
fuente
3

Una regla general: ¡no reinventes la rueda!

Aunque el código que proporcionó probablemente no es explotable, hay algunas buenas razones para usar declaraciones preparadas (una buena marco de persistencia es aún mejor) siempre que sea posible:

  • Las declaraciones preparadas son eficiente
  • No desea encargarse de todos los resultados posibles de alimentar caracteres exóticos a su motor de expresión regular (consulte mysql_escape_string () fiasco)
  • En relación con el punto anterior: si los datos del usuario se almacenan / codifican / forman de manera no trivial contrabando de SQL puede ser posible
  • En su ejemplo, la defensa se implementa en dos fases: tanto el RE como la expresión SQL deben ajustarse teniendo en cuenta el otro componente. A medida que su base de código comience a crecer (y quizás otros desarrolladores se unan), será difícil seguir siempre los dos pasos y cometerá un error explotable, tarde o temprano
respondido por el buherator 04.07.2013 - 15:04
fuente
0

La inyección SQL funciona es el soporte de MySQL para los literales hexadecimales y el hecho de que la columna de identificación de la tabla de votación es de un tipo de cadena, como en ese caso se aplica lo siguiente:

En contextos de cadena, actúan como cadenas binarias, donde cada par de dígitos hexadecimales se convierte en un carácter:

mysql> SELECT 0x0f+0;
    -> 15

Para PHP 0x ... es numérico (es decir, is_numeric) y para MySQL 0x ... se interpreta y almacena como una cadena, que luego se inserta en la declaración SELECT mencionada anteriormente.

Esto tampoco sería posible si

id habría sido un tipo de datos numérico, o SELECT hubiera sido una declaración preparada.

Por lo tanto, las cargas útiles hexencodificadas pueden pasar cuando usted permite que 0-9 y a-z puedan usarse para inyectar cargas útiles codificadas en hexadecimal comenzando con 0x [0-9a-f] .....

    
respondido por el Aayush 18.09.2018 - 17:17
fuente

Lea otras preguntas en las etiquetas