Contenido

Mejora la seguridad de tus scripts con sprintf() y printf()

10 sep

+ 6

Por desgracia las aplicaciones web no son seguras, nos guste o no, lo que hoy es seguro mañana no lo será. Alguién encontrará una forma de hacer añicos tu trabajo con una sucesión de carácteres a modo de exploid. Aprovechando aguna vulnerabilidad que por descuido o desconocimiento has dejado ahi, esperando a que nunca nadie la encuentre…

Para evitar que nunca nadie las encuentre, nuestro deber como desarrolladores es formarnos constantemente y estar al tanto de las nuevas mejoras y funcionalidades que van saliendo referente al lenguaje que estamos usando asiduamente. Quiero aportar un granito de arena recomendando esta forma de controlar nuestras peticiones a base de datos al puro estilo Google Gears.

sprintf(), protegiendo las peticiones

sprintf() es una función de php, (portada de C/C++) en la que podemos especificar el formato que ha de tener una cadena. Esta función nos permite hacer cosas como estas.

$sql = sprintf("SELECT nombre FROM tabla WHERE id = %d;",$numero);
mysql_query($sql);

De esta forma tan simple, estaremos indicando que la variable $sql, solo contendrá un número como parámetro para la consulta por id. Previamente a la utilización de $numero, deberemos tratarla para evitar que esto sea otra cosa que un número entero. En caso de pasarle un valor diferente a un entero la SQL dará un error de formateo al no reemplazar el valor.

Otros operadores

  • % – un caracter de porcentaje literal. No requiere argumento.
  • b – el argumento es tratado como un entero, presentado como un número binario.
  • c – el argumento es tratado como un entero, y presentado como el caracter con ese valor ASCII.
  • d – el argumento es tratado como un entero, y presentado como un número decimal (con signo).
  • e – el argumento es tratado como notación científica (p.ej. 1.2e+2).
  • u – el argumento es tratado como un entero, y presentado como un número decimal sin signo.
  • f – el argumento es tratado como un flotante, y presentado como un número de punto flotante (teniendo en cuenta la localidad).
  • F – el argumento es tratado como un flotante, y presentado como un número de punto flotante (no tiene en cuenta la localidad). Disponible desde PHP 4.3.10 y PHP 5.0.3.
  • o – el argumento es tratado como un entero, y presentado como un número octal.
  • s – el argumento es tratado y presentado como una cadena.
  • x – el argumento es tratado como un entero y presentado como un número hexadecimal (con letras minúsculas).
  • X – el argumento es tratado como un entero y presentado como un número hexadecimal (con letras mayúsculas).

Siguiendo la lógica

Siguiendo la lógica, ya que estamos tratando sprintf() deberíamos plantearnos desechar el polifacético echo() por printf(), de esta forma podríamos controlar la salida por pantalla al igual que en las peticiones a base de datos. El problema de usar estos métodos de forma exclusiva nos pone en el otro diléma que todo programador tiene que tener presente, el rendimiento.

Debido a sus mayores funcionalidades y opciones, sprintf(), printf(), … consumen mayor tiempo de procesador que echo() que únicamente muestra por pantalla. Por ello debemos tener presente donde usar estas funciones y donde usar otras.

Mi recomendación

Personalmente soy partidario de usar printf(), y sprintf() para todo lo referente a datos obtenidos de fuentes externas, ya sea un XML, una base de datos, otras webs,… así estaremos controlando lo único que es fácilmente alterable. Y para datos fijos, etiquetas, estructura,… usaremos echo() que aliviarán una pizca nuestro servidor.

Ampliando la seguridad

Además del uso de sprintf() y printf() tenemos a nuestra disponsición mysql_real_escape_string(), que se encarga de permitirnos validar esos parámetros sensibles de nuestros scripts. Veamos un ejemplo de como implementarlo.

$sql = sprintf("SELECT nombre FROM tabla WHERE id = %d;",mysql_real_escape_string($numero));
mysql_query($sql);

  • Buen artículo. A partir de PHP 5 (.1 si mal no recurdo) vienen las librerias PDO (PHP data Objects) que, entre otras muchas cosas, dan la posibilidad de realizar consultas preparadas (o “parametrizadas”) que funcionan de manera muy similar a lo que has explicado. Es otra alternativa, y de paso nos estariamos acercando un poco a PHP5 a la vez que dejamos de lado las ya viejitas funciones mysql_****

    Saludos!

  • Muy buen aporte Federico, y a veo que en tu blog hablas de ello ( PDO )

    Un saludo

    P.D
    Por cierto muy bueno tu blog

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.