2009-02-10 27 views
20

¿Por qué necesitamos funciones específicas de DB como mysql_real_escape_string()? ¿Qué puede hacer que addslashes() no lo haga?¿Qué hace mysql_real_escape_string() no agrega esolas()?

Ignorando por el momento la alternativa superior de las consultas parametrizadas, es una aplicación web que usa addslashes() exclusivamente aún vulnerable a la inyección SQL, y si es así, ¿cómo?

Respuesta

19

Las marcas secundarias generalmente no son lo suficientemente buenas cuando se trata de cadenas codificadas en varios bytes.

+5

Cualquier codificación con un carácter multibyte válido que termine en 0x5c puede introducir comillas pasadas 'addslashes()'. Chris Shiflett tiene un excelente ejemplo en su blog usando GBK. http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string – Matthew

+1

Eres _right_, pero no dijiste _how_. – bobobobo

+1

Todo lo contrario: en general, las pestañas son correctas, pero en algunos casos extremadamente raros, realmente necesitamos mres. –

0

Se supone que debe escapar cadenas para MySQL de una manera que otras instalaciones de citas no lo hacen.

Mucho preferible, sin embargo, es utilizar la interfaz mysqli, y usar consultas preparadas parametrizadas en lugar de intentar asegurarse de que todas las cadenas se hayan escapado correctamente. El uso de consultas parametrizadas evita la necesidad de un trabajo de cadena tan complicado y mitiga en gran medida el riesgo de inyección de SQL.

Editar: Aclararé un poco sobre por qué considero citar una mala idea: es fácil olvidar cuándo y dónde tiene que citar, si su variable debe ser una cadena o un número, si ya se ha citado. , etc. Una consulta parametrizada no tiene ninguno de estos problemas, y la necesidad de cotización es obviada por completo.

+0

Supongo que debo aclarar que soy perfectamente consciente de la superioridad de las consultas parametrizadas :) –

3

somedb_real_escape_string() es una base de datos específica, addslashes() no lo es.

En el caso de MySQL esto significa:

mysql_real_escape_string() llama biblioteca mysql_real_escape_string función de MySQL, que antepone barras invertidas a los caracteres siguientes: \ x00, \ n, \ r, \, ', "y \ X1A.

(del manual.)

1

el único La diferencia real que conozco es que mysql_real_escape_string() tomará en consideración el conjunto de caracteres de la base de datos al escapar de la cadena de entrada. Ninguna función escapará de los caracteres comodín% y _, lo que aún deja la secuencia de comandos abierta a alguna inyección SQL.

+0

% y _ no tienen nada que ver con la inyección de SQL. –

+0

En MySQL,% se puede usar como comodín en las sentencias GRANT. También MySQL trata a _ como comodín de un solo carácter en las declaraciones. – nabrond

+0

% y _ no tienen nada que ver con la inyección de SQL. –

19

Se añade barras a:

\x00, \n, \r, \, ', " and \x1a. characters. 

Dónde addslashes sólo se suma barras a

' \ and NUL 

Ilias article es también bastante detallada sobre su funcionalidad

1

De acuerdo con la PHP manual:

mysql_real_escape_string() llama a la función de biblioteca de MySQL mysql_real_escape_string, que antepone barras diagonales inversas a los siguientes caracteres: \ x00, \ n, \ r, \, ', "y \ x1a.

5

gs tiene una respuesta duramente desestimada en realidad es un poco correcta.

SQL estándar utiliza el doble para escapar de un apóstrofo literal. El uso no estándar de MySQL de barras diagonales para escaparse es la configuración predeterminada, pero se puede deshabilitar y a menudo lo es, en particular en sql_mode ANSI.

En este caso solo funcionará la sintaxis duplicada, y cualquier aplicación que tenga usando addslashes (u otro método de escape ad-hoc) se romperá. mysql_real_escape_string usará el método de escape que sea mejor para el sql_mode de la conexión.

El problema de la codificación multibyte también es importante si todavía está utilizando esas desagradables codificaciones del este de Asia que reutilizan los 128 caracteres inferiores, pero en realidad quiere usar UTF-8 en su lugar. \ n-escaparse, por otro lado, no tiene importancia ya que MySQL perfectamente puede hacer frente a una nueva línea en una declaración.

1

función mysql_real_escape_string de PHP, más o menos, pedir MySQL qué personaje (s) necesita ser escapado, donde la función addslashses sólo agregará una barra invertida delante y cualquier comilla simple ('), comillas dobles ("), barra diagonal inversa() o NUL (el byte NULO).

Los dos efectos prácticos son, agregalas tiende a no funcionar bien con caracteres multibyte, y, más importante aún, al preguntar a mysql qué caracteres deben escaparse, usted evita una posible compatibilidad futura. Usar los sesgos es como codificar un par de caracteres específicos en la secuencia de escape.

0

Según tengo entendido, mysql_real_escape_string() realiza el trabajo de manera más precisa, ya que se comunica con db para verificar primero qué necesita ser codificado y luego codificar en consecuencia, ¿no es así? Así que hay para que funcione de manera más eficiente

por qué quiere hacer en primer lugar addslashes y luego va a quitar ese barras diagonales antes de mostrar que los datos y todavía addslashes no es tan eficiente como mysql_real_escape_string, utilizar mysql_real_escape_string si está utilizando mysql_query como funciones DB para quering, o creo que de orden de pago a preparar es mejor manera, como mysql_real_escape_string es db específica

4

mysql_real_escape_string hace mucho más de addslashes hace.

addslashes opera en ascii puro, sin saber nada de la base de datos. Se escapa:

  • '\'
  • "\"
  • \\\
  • ASCII 0\0.

mysql_real_escape_string tiene como objetivo "crear una cadena SQL legal que puede usar en una instrucción SQL". mysql_real_escape_string tiene en cuenta el conjunto de caracteres actual de la conexión (por lo que siempre debe pasar un objeto $ mysql válido).

Se hace lo siguiente (tomado de la documentación de la API MySQL C):

  • Codifica: \, ', ", ASCII 0, \n, \r, y Control+Z de una manera que no cause problemas
  • asegura un byte 0 termina la cadena (en la API C)
  • puede realizar una multibyte (ASCII) para la conversión de caracteres anchos si el PP vincula en $ MySQL usa aw juego de caracteres ide

Realmente no sé cómo PHP almacena cadenas internamente, pero el punto es que todo esto está disponible para PHP cuando usa mysql_real_escape_string. Supongo que el principal punto de diferencia es mysql_real_escape_stringconsidera que el conjunto de caracteres de la conexión, donde addslashes no puede (ni siquiera sabe a qué DB está conectado).

+0

La mayoría de los puntos no tiene sentido. addslashes crea una cadena de SQL no menos legal, sea lo que sea que signifique. mres no tiene conversión de caracteres en absoluto. y no tiene sentido terminar las cadenas con NUL. ¿De dónde sacaste todo eso? –

+0

Directamente de la documentación. Multibyte se puede convertir a ancho. ["La cadena apuntada por desde debe ser de longitud de bytes. Debe asignar al búfer para que tenga una longitud mínima de 2 + 1 bytes. (En el peor de los casos, es posible que sea necesario codificar cada carácter con dos bytes, y necesita espacio para el byte nulo de terminación.) "] (http://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string.html). Supongo que la biblioteca PHP invoca la función de API de C 'mysql_real_escape_string' bajo el capó. – bobobobo

2

¿Por qué necesitamos funciones específicas de DB como mysql_real_escape_string()?

En realidad, la mayoría de las veces no es así.
Esta función es necesaria para algunas codificaciones extremadamente raras y para embellecer un poco los registros y volcados de mysql.

es una aplicación web que usa addslashes() exclusivamente aún vulnerable a la inyección SQL?

Mientras se está usando cualquier juego de caracteres de un solo byte o UTF-8 - que es perfectamente seguro con addslashes().

¿Qué puede hacer que addslashes() no?

Puede proteger SQL cadena literal en el caso de algunas codificaciones raras.

Sin embargo, no puede hacerlo solo. Primero se debe establecer una codificación adecuada utilizando la función mysql_set_charset(). Si no se ha utilizado esta función, mysql_real_escape_string()se comportaría exactamente de la misma manera que addslashes() en términos de manejo de conjunto de caracteres; no habría ninguna diferencia en absoluto.

+0

__Siempre y cuando use cualquier juego de caracteres de un solo byte o utf8__, es perfectamente seguro con addslashes(). ¿Por qué usarías 'addslashes' como una práctica donde de repente tienes que cambiar tu práctica tan pronto como trabajas con Unicode? – bobobobo

+0

Es desafortunado que desde PHP debe [establecer el conjunto de caracteres en el nivel del servidor o usar 'mysqli_set_charset'] (http://www.php.net/manual/en/mysqli.real-escape-string.php). Este no es el caso de C. – bobobobo

+1

@bobobobo "[addslashes es perfectamente seguro con] utf8 ... ¿Por qué usará addslashes [si] de repente tiene que cambiar su práctica tan pronto como trabaje con Unicode?" Tu no entiendes; UTF-8 * es * Unicode. Los únicos casos vulnerables son los juegos de caracteres ** no Unicode ** como GBK. Es decir, addslashes() es perfectamente seguro para cualquiera que use Unicode, y solo es inseguro para las personas que eligen usar juegos de caracteres nacionales raros ** en lugar de ** Unicode. – Quuxplusone

Cuestiones relacionadas