Conversiones peligrosas en MySQL

La informática demuestra que por más tiempo que llevemos, siempre nos encontraremos cosas que nos puedan sorprender, como por ejemplo el rendimiento de adición de elementos a un array en PHP. Hoy os traigo otra sorpresa, que tal vez sea menos agradable.

Tradicionalmente se ha recomendado en MySQL, forzar los parámetros numéricos a cadena dentro de las consultas, para evitar errores de tipo, y que por tanto fallen las queries.

Así por ejemplo, en vez de escribir:

SELECT * FROM t_mstr_agenda WHERE agenda_id=47

Escribíamos:

SELECT * FROM t_mstr_agenda WHERE agenda_id='47'

Cuando por el motivo que sea, ese 47 ya no es un numérico, quedamos protegidos del error, no retornándose ningún registro:

SELECT * FROM t_mstr_agenda WHERE agenda_id='ABC'

Lamentablemente si ese string, es convertible, aunque sea parcialmente a un numérico, MySQL efectuará directamente la conversión, reportando la advertencia query – Error Code 1292 – Truncated incorrect DOUBLE value:

SELECT * FROM t_mstr_agenda WHERE agenda_id='1-5W38'

No sería nada grave, si no fuera porque PHP no nos informará de esa advertencia, y transformará la consulta anterior, convertida directamente a numérico:

SELECT * FROM t_mstr_agenda WHERE agenda_id='1'

Es decir, estamos pidiendo un registro con identificador 1-5W38, que no debería existir, pero él nos está devolviendo el que corresponde a 1. El cambio tiene su origen en MySQL 5.1, y aunque se generó bastante debate al respecto, incluso criticando que el texto del mensaje no es suficientemente preciso, todo sigue 4 años después exactamente igual, en lo que a mi respecta, un indicio más acerca de la decadencia de MySQL.

Ante esto, podemos configurar MySQL en modo strict, de manera que esta casuística sea tratada siempre como un error, y por ende, falle la ejecución de la consulta. O bien, podemos dejarla como un entero, y asegurarnos que sea PHP el que lo convierta.

Conversiones peligrosas en MySQL

2 comentarios en “Conversiones peligrosas en MySQL”

  1. En mi opinión se debería de tratar el SQL como un elemento débil, por tanto todas las variables y cadenas deberían de estar convenientemente comprobadas antes de ejecutar cualquier consulta… el no hacerlo así es el origen del SQLInjection y otros ataques a las BBDD.

    Así pues, de la misma manera que cuando procesamos un formulario no debemos fiarnos jamás de los datos recibidos, con respecto al SQL los datos exteriores a la BBDD deberían considerarse poco fiables y por tanto de obligada comprobación antes de introducirlos en una sentencia.

    Saludos

  2. Javier Gutiérrez Chamorro (Guti)

    Tenes razón en lo de comprobar los valores, pues es el eslabón débil Fernando.

    Sin embargo lo curioso de este caso, es que esos datos provenían de otro sistema (una base de datos Oracle 11), y no del usuario. PHP los transformaba a MySQL, y de ahí vinieron los comportamientos inesperados.

Deja un comentario