2010-06-01 23 views
5

Esto podría ser una pregunta estúpida. O tal vez mis habilidades de pirateo son limitadas (no las practico para nada).¿Son seguras las consultas multilínea sql-injection?

Tengo una consulta que tiene este aspecto:

<?php 
$query =<<<eot 
    SELECT  table_x.field1, 
       table_x.field2, 
       table_y.*, 
       table_z.field4 
    FROM  (
        SELECT ... 
       ) as table_y 
    LEFT JOIN table_x 
    ON   table_x.field1 = table_y.field_x 
    LEFT JOIN table_z 
    ON   table_z.field1 = table_y.field_z 
    WHERE  table_x.field3 = '$something' 
    AND   table_z.field4 = '1' 
    AND   table_z.field5 = '2' 
eot; 
?> 

Tengo un montón de otras pruebas en $something antes de que se utiliza, como $something = explode(' ',$something); (que más tarde resulta en una cadena) ninguno de ellos tiene la intención de prevenir inyección, pero hacen que sea difícil para la inyección dada llegar a la consulta real. Sin embargo, hay maneras. Todos sabemos lo fácil que es reemplazar un espacio por otra cosa que todavía es válida.

Por lo tanto, no es realmente un problema hacer que una parte potencialmente dañina de SQL alcance ese $something ... ¿Pero hay alguna forma de comentar el resto de la cadena de consulta original si es multilínea?

que puedo comentar AND table_z.field4 = '1' usando ;-- pero no puedo comentar lo siguiente AND table_z.field5 = '2'

¿Es posible abrir un comentario de varias líneas /* sin cerrar o algo parecido y por lo tanto permitir la inyección de ignorar la multi- consulta de línea?

Respuesta

4

No es seguro. Incluso si no puede comentar el resto, podría prefijarlo con SELECT * FROM my_table WHERE 1 = 1.

+0

Gracias Adam, tienes razón. Es fácil piratear esta consulta multilínea. Lástima de mí por no ver esa opción. Esto es sin embargo un ejemplo y mi situación es un poco más complicada. Como no me explico, aceptaré tu respuesta como correcta. – acm

5
$something = "'; DROP TABLE table_x; SELECT * FROM table_z WHERE '1' = '1"; 
2

Uso preparado estados para estar seguro:

http://www.php.net/manual/en/pdo.prepare.php

interpolación de cadenas siempre tiene el riesgo de inyección de código si su entrada no está suficientemente limpio.

Eliminar la posibilidad de ejecutar código arbitrario es la manera más fácil Y mucho más segura.

+0

+1 Esta es realmente la única respuesta correcta. "Limpiarse" es tan bueno como su conocimiento de la inyección SQL. Deje que la base de datos/ORM probado lo maneje por usted. – richsage

2

@Techpriester: esa no es una declaración preparada.

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html (versión antigua, la misma cosa)

DOP es una capa de abstracción de base de datos que "prepara los estados", sino una declaración preparada es algo completamente diferente!

+1

PDO emula las declaraciones preparadas por defecto, pero puede desactivar este modo '$ pdo-> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false);' ¡Mire su registro general de consultas de MySQL y vea cómo funciona! –

Cuestiones relacionadas