2009-11-05 23 views
36

He estado leyendo acerca de los ataques de inyección SQL y cómo evitarlos, aunque parece que nunca puedo hacer que los ejemplos "horribles" que se ofrecen funcionen, p. see this post.¿La inyección SQL es un riesgo hoy en día?

Creé un archivo PHP y una tabla en la base de datos, tuve un valor pasado a través de $_GET e intenté eliminar la tabla haciendo bob'); drop table students; -- y no funcionó. PHP escapa automáticamente del \' y la consulta tiene un error, no hay daño. Mismo problema cuando se trata de replicar de inicio de sesión "ataques" como AND WHERE 1=1 etc.

código

ejemplo:

<?php 
$id = $_GET['id']; 

$sql = "INSERT INTO Users (Username) VALUES ($id)"; 
echo $sql; 
mysql_query($sql) or die(mysql_error()); 

Y me gustaría pasar sql.php?id=1); delete from Users; --

Entonces esto es algo anticuado que utiliza para aplicar en el días de PHP3 o algo así, y hoy en día, incluso los principiantes están protegidos de cosas como citas mágicas?

Estoy usando PHP5 en Ubuntu.

+0

Su pregunta sigue siendo muy relevante. Deberías ver las respuestas en alguna publicación de la etiqueta PHP. Por ejemplo, esto: http://stackoverflow.com/a/11908119/220060 - surgen una y otra vez. Tal vez con estos escáneres automáticos de vulnerabilidad, mueran como moscas. Me encontré con el primero exitoso de 2010. La página de inicio de nuestra empresa fue pirateada minutos después del ataque. – nalply

+1

@ tereško No creo que sea un duplicado exacto. Esa pregunta es preguntar * cómo * prevenir las inyecciones. Esta pregunta es: * por qué * las citas mágicas no son formas aceptables de prevenir las inyecciones. – luiscubal

Respuesta

57

Todo lo contrario. Las comillas mágicas están en desuso en PHP5 y se eliminarán por completo en PHP 5.4, ya que trajeron más confusión al mundo de la programación que lo hicieron bien. Comprobar si las comillas mágicas están activas, y escapando cualquier entrada de SQL escrupulosamente si es necesario, sigue siendo muy, pero muy importante ... No hay razón para sentirse mal, todos hemos estado allí, y mi culo sin saber se ha salvado mediante citas mágicas incontables veces :)

El PHP manual en magic quotes lo explica todo.

+0

¿Por qué es importante si no puedo estropear la base de datos, incluso si lo intento?Puedo ver el SQL original, lo que hace que sea más fácil para mí que un atacante. Vería la importancia de escaparse de entrada si los ataques realmente funcionaron. – Richard

+14

Es importante porque algún día, su servidor pasará a PHP 6, omitirá magic_quotes de allí en adelante, y de repente, los ataques son posibles. –

+7

El hecho de que un intento haya fallado no significa que todo lo hará. También te estás perdiendo el sentido de este comentario: lo que te está salvando en esta situación está siendo eliminado de PHP. – ceejayoz

35

No, esto sigue siendo muy relevante.

Como son XSS y CSRF. Nunca subestimes la importancia de un filtrado de entrada adecuado.

+2

La inyección de SQL y las secuencias de comandos entre sitios todavía son desenfrenadas. –

+0

+1: para encontrar ejemplos que no funcionan con su configuración específica. Seguir mirando. Los hackers serios están analizando la fuente de PHP5 tratando de encontrar una forma de escapar. Solo porque no seas tan malicioso como ellos no significa mucho. Encontrarán el agujero en PHP. Deseará no haber pasado SQL en función de la entrada del usuario. –

+0

-1: sin explicación. cf. con la respuesta de Pekka Gaiser, que explica por qué el ataque particular intentado por el OP no está funcionando en su configuración particular. –

7

Esto es un riesgo muy activo, las citas mágicas intentan darte una solución, pero prefiero desarrollarlas siempre con comillas mágicas. De esta manera, tengo que asegurarme de que realmente escapo de las entradas. Quién sabe si las comillas mágicas estarán activadas o desactivadas en el servidor donde se implementó realmente el script.

3

No, y cuanto menos te preocupes por la inyección de SQL, es más probable que te golpee.

7

Esto sigue siendo un gran problema. No puede suponer que magic_quotes está activada en cada instalación de PHP que pueda usar.

Para ver si qotes mágicos esté encendido y limpiar el desorden de comillas mágicas:

if (get_magic_quotes_gpc() !== 0) { $foo = stripslashes($foo); } 

A continuación, la limpieza de sus declaraciones un poco:

$foo = mysql_real_escape_string($foo); 
$sql = "select * from foo where bar='{$foo}'"; 

etc.

De hecho, es mejor que se limite estrictamente a magic_quotes si tiene la capacidad para hacerlo.

Espero que eso te ayude.

10

Ese ataque en particular no funciona, ya que mysql_query solo ejecutará una sola instrucción.

Aún así puedo abusar de tu código, p. si hice arreglos para que el ID sea SELECT password FROM Users WHERE Username='admin', es posible que tenga una oportunidad de poder lograr que su sistema exponga alguna información interna.

Básicamente, si permite la entrada no filtrada en su SQL, habrá algunas maneras muy creativas de crear datos que no esperaba y de exponer los datos que no pretendía.

+0

Entonces, si mysql_query solo hace una declaración, estoy a salvo de eso también ...? – Richard

+0

Estás a salvo de que alguien abandone tu tabla de usuarios. Aquí es vulnerable a iniciar sesión como lo desee. – jmucchiello

+2

No puede simplemente anexar un segundo enunciado si mysql_query lo ha ejecutado, pero puede crear una cadena que contenga una subconsulta, que era a lo que me dirigía. Esta subconsulta se puede usar para examinar su base de datos o efectuar cambios en el comportamiento de la consulta prevista. –

3

Parámetros pasados ​​a las consultas de sql desde las páginas web ofen tienden a ser ID numéricos. Por ejemplo supongamos que usted tiene una url http://foo.com/page.php?section=34 de la que se utiliza el ID de la sección de una consulta como esta:

SELECT content FROM sections WHERE section_id=$section; 

sin comillas escapen al igual que en su ejemplo y lo que voy a poner a continuación del número en el URL pasa a la consulta ... Por lo tanto, el riesgo es real.

+0

'intval()' es tu amigo. O bien, la reciente extensión 'filter' en PHP. –

+0

@Bill Karwin - Por supuesto. Mi punto es que la inyección SQL sigue siendo un problema si descuidas estas técnicas ya que no hay nada que te proteja automágicamente. – quosoo

+0

Sí, definitivamente. No he encontrado ninguna herramienta o técnica que sea una prueba perfecta contra la inyección de SQL, salvo el rastreo diligente del origen de cada variable interpolada en una cadena SQL. –

7

El ejemplo de las tablas bobby no funcionará con la interfaz mysql porque no hace múltiples consultas en una sola llamada. La interfaz mysqli es vulnerable al ataque de consulta múltiple. La interfaz mysql es más vulnerable al ataque de refuerzo de privilegios:

En su formulario escribo la cuenta: admin contraseña: ' or 1=1 -- para que su inicio de sesión típico sql: select * from users where user_name = '$admin' and password = '$password'. El o hace que esto sea cierto y le permite iniciar sesión.

+0

Puedo ver cómo esto funcionaría, sin embargo esto no afectará a las personas que encriptan sus contraseñas, o incluso si no lo hacen, escriben consultas en forma de seleccionar contraseña de Usuarios donde nombre de usuario = 'blah' y luego comparan la contraseña a la contraseña presentada. – Richard

+0

Richard, cambiando la forma del SQL es un tipo de protección de inyección SQL. La prevención de la inyección SQL requiere que use SQL cuidadosamente. La solución de SQL para validar a un usuario es hacer la selección si no se encuentra, el usuario no está validado. Esa solución ignora la realidad de la web. Entonces, para trabajar, debe modificar su SQL para lidiar con la realidad de la web. – jmucchiello

3

La regla de oro más simple es suponer que todos los usuarios input pueden estar contaminados. Verifique que los tipos de datos sean los esperados, que las variables estén en los rangos de longitud/tamaño que esperaba, los archivos sean del tamaño y tipos que permita, etc. Se pueden requerir otras comprobaciones de datos no externos, antes de llamar a un administrador importante. -función de nivel, haz una verificación - ($userlevel != ADMIN)?die():important_function();

Siempre hay un pez más grande, o alguien que es un idiota más grande que tú. Evita los supuestos sobre los datos y tienes una ventaja.

+0

la comprobación del administrador debe estar dentro de su función importante – Kris

+0

@Kris: Ahora que lo menciona ... así es como lo hago. Estaba pensando en el control que hago en el código, pero olvidando que lo hago al principio de la función. Estás 100% en lo cierto. –

4

Hay muchas maneras diferentes de realizar una inyección SQL y bastantes formas de eludir las precauciones básicas de seguridad.

Esos ataques han estado dentro de las 10 principales vulnerabilidades de aplicaciones web (rango n.º 2) según OWASP. Para obtener más información, consulte Top 10 2007-Injection Flaws.

7

¿No puede PHP hacer los parámetros de consulta? Si puede (como me sorprendería si no lo hiciera), esa es la única solución que mitiga TODOS los ataques de inyección de SQL.

+1

La extensión mysql que usa la mayoría de la gente en PHP no puede hacer parámetros de consulta. La extensión mysqli ligeramente más avanzada y el controlador PDO mysql * do * admiten los parámetros de consulta, pero la antigua extensión mysql aún se usa más ampliamente. –

+0

por desgracia, Bill Karwin tiene razón, ¡así que deja de enseñarle a la gente de la vieja y anticuada interfaz de mysql! – Kris

+0

Lo siento, no tenía la intención de comenzar una guerra de llamas. Estoy honestamente sorprendido. – erikkallen

15

Las comillas mágicas no tienen en cuenta la codificación de caracteres y, por lo tanto, son vulnerables a los ataques basados ​​en multi-byte caracteres.

En cuanto a que es un riesgo hoy en día, las búsquedas de Google aparecen en innumerables sitios vulnerables. Se notificó una vulnerabilidad de inyección SQL para Bugzilla alrededor del 10 de septiembre. Por lo tanto, sí, los sitios aún están en riesgo.¿Deberían serlo? Las herramientas están ahí para prevenir la inyección, entonces no.

+0

+1 para vincular el artículo de Chris Shiflett sobre conjuntos de caracteres exóticos. –

+0

+1 por la misma razón de mí también – Kris

20

El robo de identidad más grande en la historia se logró en 2007 mediante la explotación de una vulnerabilidad de inyección SQL: ver "SQL injection attacks led to Heartland, Hannaford breaches" (ComputerWorld, 18/08/2009).

OWASP reported in 2007 que los ataques de inyección (de los cuales la inyección SQL es un ejemplo) continúan siendo uno de los problemas de seguridad de software más comunes.

También puede buscar los últimos SQL injection News y encontrar muchos casos reportados cada mes.

Sin embargo, el ejemplo en la caricatura XKCD no es necesariamente el tipo más común de exploit. Dejar caer una tabla ejecutando una segunda instrucción SQL en una solicitud probablemente no le ganaría mucho al atacante en el camino de datos valiosos, sería simplemente vandalismo.

Además, algunas interfaces de consulta no permiten multi-query de forma predeterminada. Es decir, la API del cliente de la base de datos ejecuta una única instrucción dada la cadena SQL, independientemente de los puntos y comas. Esto derrota el ejemplo que se muestra en la caricatura.

nota: método de DOP query() se sabe que el apoyo múltiples consulta por defecto. Por lo tanto, es susceptible al ataque de estilo XKCD.

Como han señalado otras personas, el riesgo más probable es que una inyección SQL altere la lógica de las expresiones SQL y aplique su consulta a filas adicionales además de las que pretendía.

Por ejemplo:

$sql = "UPDATE Users SET PASSWORD = MD5('" . $_POST["password"] . "'||salt) " . 
     "WHERE user_id = " . $_POST["userid"]; 

Lo que sucede cuando envío una solicitud con el parámetro establecido userid a la cadena 123 OR userid=456? Me gustaría restablecer mi propia contraseña (ID de usuario 123), así como la contraseña de ID de usuario 456. Incluso el hash de la contraseña con una sal por usuario no protegería contra esto. Ahora puedo iniciar sesión en cualquiera de las cuentas.

Hay muchas maneras en que se puede perpetrar la inyección SQL.

5

Como he mencionado varias veces en stackoverflow antes, yo soy un firme partidario de la DOP, simplemente dejar de usar el viejo MySQL moda, hágase y sus clientes un gran favor y aprender DOP (que es muy fácil) y aprovechar las declaraciones preparadas y los parámetros vinculados. Incluso si no necesita declaraciones preparadas en cuanto al rendimiento, aún obtiene los beneficios de seguridad.

Además, recomendaré colgar toda la aplicación en la cara del cliente si las comillas mágicas están activadas. Es solo un drenaje de recursos diseñados para proteger a los tontos y molestar a los inteligentes. (usa más CPU que escapando manualmente, porque codifica todo, incluso cuando no lo necesita)

+0

+1 ¡Sí a usar PDO en aplicaciones PHP! –

9

Oh mi ... La inyección SQL no es un riesgo, es un agujero de seguridad abierto. Principalmente existe en php porque la API hace que quieras interpolar cualquier dato antiguo en tus consultas SQL.

Cuando veo un sitio escrito en PHP o ASP, puedo oler los vectores de inyección SQL que apestan. Las personas intentan proteger sus aplicaciones PHP con mysql_real_escape_string() y intval() y lo hacen de manera similar en otros idiomas. Esto es un error.Es como codificar en C en lugar de en Java o Python, donde en el primero, comete un error y está muerto, pero en el segundo, solo pueden existir defectos semánticos.

Recomiendo encarecidamente a las personas que utilicen ya sea mysqli con declaraciones preparadas, o cualquier otra cosa que sea parametrizada, sustituyendo texto en código y luego interpretarlo es una mala práctica en primer lugar en mi humilde opinión.

En otra nota, las citas mágicas de PHP son simplemente tontas, y afortunadamente, desaprobadas. Solo puede causar más daño que bien. Si dependes de citas mágicas, significa que tu aplicación será propiedad cuando las comillas mágicas estén deshabilitadas. Del mismo modo, puede romper otras aplicaciones que no esperan cadenas escapadas en las entradas.

+2

Apoyo la recomendación de usar parámetros de consulta. Pero creo que es falso afirmar que la inyección de SQL se produce principalmente en PHP o ASP. Puede ocurrir y ocurre desenfrenadamente en todos los idiomas, incluidos los procedimientos almacenados SQL. –

+1

Disculpa, solo quise dar PHP y ASP como ejemplos, ya que se usan con tanta frecuencia en las bases de datos SQL. Siempre es divertido ver a la gente tratando de usar la sensibilización de entrada y printf en C, cuando podrían haber usado declaraciones preparadas. –

+1

o_O No recuerdo haber escrito "sensibilización", y tampoco bebo ... –

0

Siempre que la construcción de SQL a partir de cadenas, inyección SQL es un peligro real.

También descubrí que tratar de evitar la creación de SQL a partir de cadenas es una tarea inútil. Tarde o temprano, la forma completa de su SQL (no solo las cosas que podrían ser parámetros) debe generarse en tiempo de ejecución.

0

¡Tengo que desarrollar un servidor que no tenga forma de desactivar magic_quotes! Incluyo esto en cada página para deshacer los efectos de las comillas mágicas, por lo que puedo hacer el correcto escapando sin "doble escape". Aunque puedo saborear vómitos solo por leer esto, no he encontrado una mejor solución.

if (get_magic_quotes_gpc()) { 

    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); 

    while (list($key, $val) = each($process)) { 

     foreach ($val as $k => $v) { 

      unset($process[$key][$k]); 

      if (is_array($v)) { 

       $process[$key][stripslashes($k)] = $v; 

       $process[] = &$process[$key][stripslashes($k)]; 

      } else { 

       $process[$key][stripslashes($k)] = stripslashes($v); 

      } 

     } 

    } 

    unset($process); 

} 
0

Según OWASP 2017 Top 10, todavía la inyección es el ataque más ocurrido y peligroso.

"inyección SQL es siempre el número uno de riesgo que es un reflejo de cómo muchos incidentes están ahí fuera, así como otros factores que lo mantienen muy alta allí." Troy Hunt - fundador del sitio de incumplimiento haveibeenpwned .com

sólo para recordar, mediante la inyección de SQL podemos volcar toda la base de datos, el control de servidor web mediante la subida de la cáscara web, etc.

Cuestiones relacionadas