La principal deficiencia de mysql_real_escape_string
, o de la extensión mysql_ en general, es que es más difícil de aplicar correctamente que otras API más modernas, especialmente declaraciones preparadas. mysql_real_escape_string
se supone que debe usarse exactamente en un caso:contenido de texto de escape que se usa como valor en una instrucción SQL entre comillas. Por ejemplo:
$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
^^^^^^
mysql_real_escape_string
se asegura de que el $value
en el contexto anterior no estropea la sintaxis SQL. No funciona como puede pensar aquí:
$sql = "... `foo` = $value ...";
o aquí:
$sql = "... `$value` ...";
o aquí:
$sql = mysql_real_escape_string("... `foo` = '$value' ...");
Si se aplica a valores que se usan en cualquier contexto que no sea una cadena entrecomillada en una instrucción SQL, se aplica incorrectamente y puede estropear o no la sintaxis resultante y/o permitir que alguien envíe valores que pueden permitir ataques de inyección SQL. El caso de uso de mysql_real_escape_string
es muy estrecho, pero rara vez se entiende correctamente.
Otra forma de meterse en problemas usando mysql_real_escape_string
es cuando configura la codificación de la conexión de la base de datos utilizando el método incorrecto. Deberías hacer esto:
mysql_set_charset('utf8', $link);
Tu puedes también haz esto:
mysql_query("SET NAMES 'utf8'", $link);
El problema es que este último pasa por alto la API mysql_, que todavía cree que estás hablando con la base de datos usando latin1
(o algo mas). Al usar mysql_real_escape_string
ahora, asumirá la codificación de caracteres incorrecta y las cadenas de escape de manera diferente a como las interpretará la base de datos más adelante. Ejecutando SET NAMES
consulta, ha creado una brecha entre cómo la API del cliente mysql_ está tratando las cadenas y cómo la base de datos las interpretará. Esto se puede usar para ataques de inyección en ciertas situaciones de cadenas multibyte.
No hay vulnerabilidades de inyección fundamentales en mysql_real_escape_string
que yo sepa si se aplica correctamente. Sin embargo, nuevamente, el principal problema es que es terriblemente fácil aplicarlo incorrectamente, lo que abre vulnerabilidades.