¿Tiene mysql_escape_string alguna vulnerabilidad de seguridad si todas las tablas usan codificación Latin1?

6

He oído que la función de PHP mysql_escape_string tiene vulnerabilidades de seguridad relacionadas con multi- caracteres de byte. ¿Existen vulnerabilidades si todas las tablas utilizan codificación Latin1?

    
pregunta user5385 11.10.2011 - 05:24
fuente

3 respuestas

6

El problema es que mysql_escape_string() no comprueba la base de datos para la codificación de caracteres. Como resultado, mysql_escape_string() desconocería la codificación de su base de datos y puede tratar los caracteres de múltiples bytes como caracteres de un solo byte. Esto podría hacer que los últimos dos bytes se escapen a un carácter reservado como , así como a otros innumerables caracteres que tienen especial relevancia para el motor SQL.

En tal caso, el atacante podría agregar comandos SQL adicionales para obtener acceso a datos o funciones no deseadas. Por esta razón, la función está en desuso y se recomienda el uso de mysql_real_escape_string() .

mysql_real_escape_string() funciona de manera casi idéntica, excepto que se conecta a la base de datos para determinar qué codificación utiliza la base de datos, lo que evita los problemas conocidos de escape de múltiples bytes.

También tenga en cuenta que mysql_escape_string() y mysql_real_escape_string() no escapan a los caracteres% y _ (según la referencia del manual enlace y enlace vea las notas). Esto podría permitir el acceso a datos que no están destinados cuando se usan con palabras clave como LIKE , por lo que se debe tener especial cuidado.

Actualizar

  

Entonces, ¿qué codificación asume mysql_escape_string?

Creo que es ASCII, pero no puedo confirmar esto. Independientemente no hace ninguna diferencia al resultado que es; el uso de Latin1 para la codificación de la base de datos podría resultar en una vulnerabilidad de seguridad si no se codifica correctamente.

También tenga en cuenta que esto no es solo una vulnerabilidad con la base de datos. Dentro del script de lado de la aplicación / servidor, debe tener cuidado al manejar la entrada para saber cómo se pasan las cadenas de una función a otra y asegurarse de que se conserve la codificación correcta. Lo ideal sería utilizar UTF-8 de extremo a extremo, pero no siempre es una opción.

    
respondido por el Bernie White 11.10.2011 - 06:52
fuente
6

Personalmente, creo que estás haciendo la pregunta incorrecta. Si desea evitar las vulnerabilidades de inyección SQL, como debería, la respuesta es no usar mysql_escape_string más cuidadosamente. La respuesta correcta es utilizar declaraciones preparadas.

El problema fundamental es que mysql_escape_string es frágil, y es difícil predecir todas las formas específicas en que podría romperse. Ha aprendido una fuente de fragilidad en mysql_escape_string , y ahora se pregunta si esa es la única fuente.

Personalmente, me llevo una lección diferente. La lección que extraigo es que, si la seguridad es el trabajo, mysql_escape_string es la herramienta incorrecta para el trabajo. En su lugar, debería utilizar declaraciones preparadas (consultas parametrizadas).

En el mundo de la seguridad, se acepta ampliamente que la forma más robusta de evitar la inyección de SQL es usar declaraciones preparadas. No intente escapar / codificar sus datos y luego crear una consulta SQL utilizando concatenación de cadenas; ese enfoque es frágil y puede romperse fácilmente si, por ejemplo, la base de datos interpreta su consulta de manera diferente a lo que esperaba. Así que mi consejo es: no intente ser inteligente, solo use declaraciones preparadas y sea feliz.

    
respondido por el D.W. 11.10.2011 - 08:20
fuente
1

Por @ la respuesta de BernieWhite , mysql_escape_string() realiza un escape en completa ignorancia de la codificación de la cadena que realmente se está utilizando < em> para la conexión de base de datos (que es independiente de la utilizada en sus tablas).

Por lo tanto, intenta escapar de los caracteres ' reemplazándolos con \' cuando ocurren. Hace esto en forma de bytes, reemplazando cada aparición de 0x27 con 0x5c27 (es decir, está operando efectivamente bajo el supuesto de que la cadena está codificada en un superconjunto de un solo byte de ASCII); por ejemplo, convertirá la cadena 0xbf27 en 0xbf5c27 , pero si la codificación de la conexión es GBK, esto convertirá una cadena no válida en 縗' (tenga en cuenta el carácter ' sin escaparse).

Por lo tanto, mysql_real_escape_string() se introdujo para realizar el escape correctamente, es decir, de acuerdo con la codificación de caracteres de conexión. Sin embargo, por lo tanto, uno debe informar a la biblioteca del cliente de la codificación de caracteres llamando a mysql_set_charset() : este paso a menudo se pasa por alto, y lo hace tan vulnerable como si se estuviera utilizando el mysql_escape_string() original.

Pero incluso si uno usa mysql_real_escape_string() , todavía hay otros casos de borde que pueden dejarlo vulnerable. Como se explica en mi respuesta a la "inyección de SQL que circula mysql_real_escape_string ()" sobre StackOverflow:

  

TL; DR

     

mysql_real_escape_string() no proporcionará protección alguna (y además podría munge sus datos) si:

     
  • NO_BACKSLASH_ESCAPES de MySQL está habilitado (el cual < em> podría ser, a menos que explícitamente seleccione otro modo SQL); y

  •   
  • sus literales de cadena SQL se citan usando comillas dobles " caracteres.

  •   

Debido a estas dificultades prácticas para garantizar que los literales de cadenas incrustados se manejen de manera segura, generalmente se recomienda que ni siquiera lo intente. En su lugar, uno puede enviar valores literales a la conexión de la base de datos en paquetes que son completamente independientes del SQL; en consecuencia, el servidor ni siquiera intentará analizar esos valores para otra cosa: esto se conoce como "parametrización de consulta", es lo que La respuesta de @ DW sugiere, y se explica muy bien en ¿Cómo puedo prevenir la inyección de SQL en PHP? ?

    
respondido por el eggyal 25.04.2014 - 17:03
fuente

Lea otras preguntas en las etiquetas