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.