Hay que destacar que sprintf no elimina todos los problemas de seguridad, pero si lo hace bastante más confiable. También que este es uno de lo tantos metodos que existen para brindar mayor seguridad, pero siempre hay que tenerlo en cuenta mientras se programa.
Consulta VulnerableImaginemos que la consulta está esperando un entero, que en este caso seria 6.
$ID = "6 OR id != 0" ;
$Query = "DELETE FROM Tabla WHERE id = " . $ID;
Como se permitió especificar más de la cuenta, estaríamos eliminando todo lo que tenga ID = 6 o distinto a 0. Esto significa que el usuario fue capaz de eliminar todo los registros de la tabla.
SoluciónSi se hubiese utilizado sprintf, este desagradable hecho se podría haber evitado. Ahora vamos a utilizar el mismo ejemplo anterior, pero utilizando sprintf
$ID = "6 OR id != 0" ;
$Query = sprintf ("DELETE FROM Tabla WHERE id = %d" , $ID);
¿Qué ocurrirá? Eliminara solo lo que tenga ID 6. Esto es porque se ha utilizado un tipo de especificación (lo veremos más adelanta), el cual el argumento debe ser un entero y nada más. Entonces la consulta que se realizaría seria.
DELETE FROM Tabla WHERE id = 6
Como trabaja sprintfSe me olvidaba algo bastante importante, que es cómo funciona sprintf.
- Hay que especificar el primer argumento que es la cadena que deseas utilizar
- Se utiliza %d, %s, etc... Según el tipo de valor que se quiere utilizar
- Después de declarar el primer argumento de sprintf, se indica las variables según el orden que se quieran mostrar.
Para entender el último punto mejor, daré un ejemplo. Si tuviera.
$VarA = "Hola";
$VarB = "Mundo";
printf("%s %s",$VarA,$VarB);
Esto imprimiría.
Hola Mundo
Pero si se invierten $VarA por $VarB y viceversa
$VarA = "Hola";
$VarB = "Mundo";
printf("%s %s",$VarB,$VarA);
Imprimiría.
Mundo Hola
*En este caso he utilizado printf ya que cumpliría una función similar a echo() o print()
*En los ejemplos use el espeficador %s el cual interpreta como una cadenaTipos de especificación
También se les puede llamar especificadores y se utilizan dependiendo del tipo de datos que se utilizara.
- %d - El argumento es tratado como un entero y presentado con notación decimal
- %c - El argumento es interpretado como un entero, y presentado como el caracter ASCII con dicho valor.
- %e - El argumento es tratado como un entero y presentado con notación exponencial.
- %f - El argumento es tratado como un double y presentado como un número de coma flotante.
- %o - El argumento es tratado como un entero, y presentado como un número octal.
- %x - El argumento es tratado como un entero y presentado como un número hexadecimal (con minúsculas).
- %X - El argumento es tratado como un entero y presentado como un número hexadecimal (con mayúsculas).
- % b - El argumento es interpretado como un número entero, y presentado como un número binario.
- %% - Devuelve un signo de porcentaje
- % s - El argumento es tratado como una cadena y es presentado como tal.
Rendimientosprintf y printf deben usarse solo cuando tengamos que dar formato especial al texto, no con caracteres generales, ya que es más lento que echo o print.
Por último, sprintf y printf es compatible con las funciones dentro de funciones, por lo que el query se puede hacer mucho mas seguro
$Query = sprintf ("DELETE FROM Tabla WHERE id = %d" , mysql_real_escape_string($ID));
Nota: La diferencia entre una y otra es que con sprintf() volcamos la cadena a una variable, para poder trabajar con ella, mientras que con printf() nos limitamos a mostrar una cadena con formato.Artículo realizado por X-ISM para PHPeros.net
Se permite la reproducción total o parcial del contenido del artículo siempre que se mantenga el autor y una referencia a la fuente original.