2010-03-16 14 views
5
$myq = sprintf("select user from table where user='%s'", $_POST["user"]); 

Me gustaría saber si la consulta anterior puede explotarse mediante inyección de SQL. ¿Hay alguna técnica avanzada de inyección SQL que pueda romper sprintf para esta consulta en particular?¿Es esta consulta vulnerable a la inyección sql?

+0

¿Hay alguna razón por la que se opone al uso de mysql_real_escape_string? –

+0

No sé dónde lo conseguiste, pero el sprintf no escapa nada. –

+0

ACtualmente esto es parte de la asignación para encontrar la inyección sql. Repetí el escenario en mi local e intenté todas las inyecciones sql normales $ a = sprintf ("seleccionar usuario de la tabla donde el usuario = '% s'", $ _POST ["usuario"]); echo $ a Sigo obteniendo las comillas escapadas con \. ¿Hay algo en el medio que podría estar escapando de las cotizaciones? – user294924

Respuesta

25

No creo que tiene que ser particularmente avanzada ... intentar una entrada de

' OR 1 = 1 OR user=' 

En otras palabras, usted obtendrá SQL de:

select user from table where user='' OR 1 = 1 OR user='' 

se ve eso como una consulta que realmente quieres ejecutar? (Ahora considere la posibilidad de que deje caer tablas en su lugar, o algo similar).

La conclusión es que debe utilizar una consulta parametrizada.

+0

doesnt sprintf escape comillas simples? – user294924

+2

No, no es así. Al menos no en mi experiencia con PHP. –

+1

@ user294924,% s le dice al subsistema printf que imprima cualquier cadena que contengan los argumentos variados. No verifica, no filtra, no escapa ... hace exactamente lo que le dices que haga. –

4

cuando $ _POST ["usuario"] sería igual a "'; SHUTDOWN;" - ¿qué pasaría?

+0

sprintf habría escapado de comillas simples y la consulta enviada a db sería seleccionar usuario de la tabla donde user = '\'; SHUTDOWN; ' – user294924

+0

Si el póster no utiliza mysqli_multi_query, no sucederá nada porque todos los demás métodos de consulta de mysql en PHP solo ejecutan una consulta. – chiborg

0
$_POST["user"] = "' or 1=1 or user='" 
0

Sí.

Si alguien puso en lo sucesivo como el usuario en su formulario:

'; delete * from table 
+2

Aunque no funcionará con mysql habitual, es bueno, por ejemplo. –

8

Usando sprintf no le da más protección que el uso de cadena simple concatenación. La ventaja de sprintf es que es un poco más legible que cuando se utiliza una concatenación de cadenas simple de PHP. Pero sprintf no hace nada más que una simple concatenación de cadenas cuando se utiliza el formato de %s:

$str = implode('', range("\x00", "\xFF"));  // string of characters from 0x00 – 0xFF 
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true 

Es necesario utilizar las funciones que escapan a los caracteres especiales contextuales que desea insertar los datos en (en este caso un string declaration in MySQL, suponiendo que está utilizando MySQL) como **mysql_real_escape_string** hace:

$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"])); 
8

Sí, yo diría que tienes un problema potencial allí :)

usted need to escape: \x00, \n, \r, \, ', " y \x1a. sprintf() does not do that, sprintf() no modifica las cadenas, simplemente expande los argumentos variados que le das al búfer que proporciones de acuerdo con el formato que especifiques.

Si las cadenas se están transformando, es probable que se deba a magic quotes (como Rob señalado en Comentarios), no a sprintf(). Si ese es el caso, I altamente recomendamos deshabilitarlos.

+0

-1 porque: tiene que escapar mucho más que eso, y, si se le olvida hacer una en cualquier consulta, es pwned. En pocas palabras: mejor que exista una razón malditamente buena ** específica ** para construir una cadena de consulta a partir de cadenas concatenadas, de lo contrario, use parámetros siempre. – BryanH

+0

@BryanH Otras dos personas le dijeron que necesita usar consultas parametrizadas. Respondí específicamente a 'sprintf()' porque a OP le costaba entender por qué no estaba haciendo lo que pensaba que estaba haciendo (ver comentarios bajo la respuesta de Jon). No sugerí que simplemente use cadenas concatenadas :) –

1

¡Ahh aquí vengo con la respuesta mágica! :)
magic quotes ¡escapa para ti!

Por lo tanto, hay que girar magic_quotes_gpc INI Directiva fuera
y luego usar mysql_real_escape_string como se sugiere.

1

En realidad, desactive las comillas mágicas.

En PHP, donde es, filtros adecuados de uso:

$inUser = $_POST['user']; 
$outUser = filter_var($inUser, FILTER_SANITIZE_STRING); 

Filtros Franja de formularios HTML etiquetas y escapar de diversos personajes.

Además, puede dejar escapar su base de datos por usted:

$inUser = $_POST['user']; 
$outUser = mysqli_real_escape_string($conn, $inUser); 

Esta escapa caracteres especiales específicas de MySQL como comillas dobles, comillas simples, etc.

Por último, se debe utilizar consultas parametrizadas :

$sql = "SELECT user FROM table WHERE user = ?"; 
$stmt = $pdo->prepare($sql); 
$params = array($outUser); 
$stmt->execute($params); 

consultas con parámetros agregar automáticamente las comillas en cadenas, etc., y tienen más restricciones que hacen que las inyecciones SQL aún más di difícil

Uso los tres, en ese orden.

+0

¿Qué es mejor usar para filtrar POST o GET no deseados, "mysqli_real_escape_string" o "FILTER_SANITIZE_STRING"? – user345602

Cuestiones relacionadas