2010-06-14 17 views
10

El script está en PHP y como DB uso MySQL. Aquí está el script en sí.¿Esta consulta es segura desde la inyección sql?

$unsafe_variable = $_GET["user-input"]; 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 

Algunas personas dicen que si el usuario asigna ;DROP TABLE blah; cadena a la variable $ unsafe_variable se elimina la tabla.

Pero traté este ejemplo,

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

Pero no eliminó la mesa, pero en cambio inserta una nueva fila en la tabla (;DROP TABLE blah;).

¿Alguien podría explicarme cómo es posible atacar este script con inyecciones de sql?

+3

'' mysqli' o PDO' y sus declaraciones preparadas haría ser una mejor opción. – Powerlord

+0

Muchas gracias a todos los participantes de la pregunta. Realmente me di cuenta de que con solo 'sprintf' no podemos estar seguros de que nuestra consulta esté a salvo de ** sql-injections **. Para este ejemplo específico ni yo ni los participantes podríamos presentar la forma de ejecutar sql-injection. Pero he encontrado un buen ejemplo de SQL donde podemos ejecutar inyección sql incluso si usamos 'sprintf'. El ejemplo sql se puede encontrar [aquí] (http://php.net/manual/en/function.mysql-real-escape-string.php "PHP Online Manual"). Consulte la sección de 'Ejemplo # 2 Un ejemplo de ataque de inyección SQL' – Bakhtiyor

Respuesta

13

Esa inyección particular no funcionaría ya que la función mysql_query de PHP solo permite una consulta por llamada. Sin embargo, lo siguiente puede funcionar si column tiene una clave principal o único:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#"; 

mejor utilizar el prolijo mysql_real_escape_string función:

$sql=sprintf("INSERT INTO table (column) VALUES(%s)", 
      mysql_real_escape_string($unsafe_variable)); 
mysql_query($sql); 
4

mysql_query() no permite la ejecución de múltiples consultas en una función. Entonces no puedes INSERTAR y luego DEJAR caer la mesa. Pero no deberías confiar en esto como 'seguridad'. Use consultas parametrizadas en su lugar. Echa un vistazo a la biblioteca PDO de PHP.

Sin embargo, podrían cambiar casi cualquier otra cosa, como posiblemente SELECCIONAR un campo de contraseña de otra tabla como una subconsulta para colocar en esa tabla para que puedan ver el hash.

+0

http://php.net/manual/en/function.mysql-query.php –

+0

¿Alguna razón para votar a la baja? Las declaraciones preparadas son generalmente más seguras que 'mysql_real_escape_string'. –

1

No, sprintf no escapa a la utilización contenido:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]); 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 
1
mysql_real_escape_string($unsafe_variable) 
3

Mientras mysql_query sólo permite una consulta para ejecutar, en general, esta consulta no es seguro. Un ejemplo de una entrada peligrosa que explotar su consulta es:

'); DROP TABLE my_table; -- 

El '); al inicio cerrará su consulta e insertar un valor vacío, pero permitirá consultas adicionales para ser ejecutado después de la inserción. Luego, después de colocar una tabla, el -- al final marcará todo lo demás a continuación (es decir, el resto de su consulta) como un comentario.

Para preparar con seguridad la entrada para su uso en una consulta, use mysql_real_escape_string.

+0

¿Quería decir que si ejecuto este script [http: //authoringtool/test.php? User-input = ');% 20DROP% 20TABLE% 20my_table2;% 20--] ¿eliminará my_table2 de mi DB? Si no, entonces por favor dame un ejemplo real de cómo funciona, porque tu ejemplo no eliminó my_table2 :) – Bakhtiyor

+1

Como se mencionó, 'mysql_query' no es compatible con la ejecución de múltiples consultas, pero aún deberías asegurar adecuadamente tu consulta. –

1

Algunas personas dicen que si el usuario asigna, DROP TABLE blah; cadena a la variable $ unsafe_variable, borra la tabla.

Patentemente ese no es el caso, pero si no entiende por qué, entonces no puede decir si su código es seguro. ¿Vas a publicar cada línea aquí para verificar si es segura?

Sin entrar en una larga explicación sobre lo que está haciendo el código anterior y cómo ponerlo en peligro (la inyección SQL ya está muy bien documentada en otros lugares, pruebe Google para empezar) SIEMPRE debe asegurarse de que cualquier información que salga de su código PHP en la representación correcta de hacia dónde va.

Para una base de datos MySQL que significa o bien:

1) usar la salida de mysql_real_escape_string (y asegúrese de que pase el gestor de recurso derecha)

o

2) el uso de enlace de parámetros.

Una discusión adecuada de los ataques de inyección de código podría llenar fácilmente varios cientos de páginas, un poco demasiado para responder en un S.O. consulta.

C.

0

Creo que el ejemplo que tendría que intentar es http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'

la '); cierra el segmento values('%s, y luego emite un nuevo comando, drop table...

+0

Eso no funciona. – Bakhtiyor

Cuestiones relacionadas