Cómo evitar problemas con magic quotes
Las «magic quotes» de PHP, o comillas mágicas, es una desafortunada funcionalidad que se encarga automáticamente de añadir slashes a las comillas dobles y simples de la información que llega a una página vía parámetros GET, POST o a los que se guardan en cookies. Para empezar, ni siquiera el nombre es apropiado, no hay nada de mágico en ello, un nombre mucho más apropiado hubiera sido «Escapado automático de comillas».
El objetivo inicial de esta funcionalidad era que el desarrollador pudiera utilizar directamente los datos y pasarlos por ejemplo a una consulta SQL, sin tener que hacer un addslashes
previamente, sin embargo, lo que de primeras puede parecer una buena idea, se convierte en una pesadiila en cuanto se mira con un poco más de detenimiento, incluso en la propia página oficial de PHP se recomienda desactivar esta funcionalidad.
Es habitual encontrar páginas en las que el texto aparece con slashes precediendo a cualquier comilla, esto suele ser fruto de la utilización de alguna aplicación que no controla correctamente esta funcionalidad. El principal problema es la portabilidad, puedes escribir una aplicación completa utilizando esta funcionalidad, manejando incluso todos los posibles casos correctamente, para encontrarte a la hora de la verdad, cuando tienes que instalar la aplicación en un nuevo servidor, con multitud de fallos debidos a que su configuración no es la misma que tú habías utilizado.
Es por esto que desde hace mucho tiempo se recomienda desactivar la funcionalidad y desarrollar aplicaciones utilizando addslashes
, o el método de escapado que corresponda a cada situación. Aún así puede darse el caso de que lleguemos a un servidor que tenga las magic quotes activadas, con lo que al realizar un addslashes, estaríamos haciéndolo dos veces, una » enviada por el usuario pasaría a ser \\», y podría guardarse en base de datos por ejemplo como \».
Para evitar esto utilizo desde hace bastante tiempo en todos los desarrollos que hago, una función a la que llamo al comienzo de cada petición y que se encarga de revisar, en los casos en los que las magic quotes están activadas, las matrices $_GET, $_POST y $_COOKIE haciendo un stripslashes
de sus contenidos.
function& fixMagicQuotes($data) { if (get_magic_quotes_gpc() == 1){ if (is_array($data)) return array_map('fixMagicQuotes', $data); else return stripslashes($data); } else return $data; } |
Esta función hace un stripslashes sobre el parámetro de la entrada, chequeando antes si es un array, en cuyo caso se llama de forma recursiva con cada uno de los elementos de la matriz. El siguiente fragmento de código muestra un ejemplo de utilización:
$_GET =& fixMagicQuotes($_GET); $_POST =& fixMagicQuotes($_POST); $_COOKIE =& fixMagicQuotes($_COOKIE); |
Si no utilizas las variables de sistema $_GET, $_POST y $_COOKIE, sino que tienes activado el register_globals, deberías pasar esta función por los parámetros que utilices, lo cual puede ser un poco lioso y una buena fuente de errores, o sea, otra buena razón por la que no tener activadas las register_globals, pero eso es ya otra historia… 😉
Tu código, en mi opinión, no resuelve el problema principal del por qué no usar «comillas mágicas» (http://es.php.net/manual/es/security.magicquotes.whynot.php), que es el rendimiento, creo que lo más _óptimo_ sería desactivándolo en el php.ini (si se tiene acceso a éste) o con la función ini_set (no sé si funcione).
Saludos
Si Alex, sería lo ideal, pero no siempre se tiene acceso al servidor de producción.
En efecto, como dice DGtal, no siempre se tiene acceso a configurar PHP en el servidor. Yo siempre que puedo modifico el php.ini y si no puedo, lo intento con apach, pero siempre puede darse el caso de que no puedas modificar la configuración de PHP, por lo que para esos casos, incluyo siempre este código
Yo también aplico una fórmula más o menos parecida a la de DGtal, pero no parseo todas las variables que recibo.
Cree tres funciones llamadas
getPostVar(), getGetVar(), getCookieVar()
Cuándo necesito utilizar una dato que he recibido vía POST por ejemplo, hago lo siguiente:
$sNombre = getPostVar(‘form_nombre’);
La propia función getPostVar() se encarga de limpiar la slashes que posiblemente PHP haya agregado, obviamente evaluando si esta característica está activa. Es una buena forma de no usar directamente ningún valor que pueda venir «desde afuera», y naturalmente, solo parseo las variables que necesito. Nada más.
Yo no tengo acceso al php.ini y este código es bastante útil para mis propósitos.
😉
Saludos.
http://www.tecnocodigo.com
http://www.califato.com
Aunque este post es viejo, el enlace sobre la recomendacion de php es valida y realmente funciona, gracias.