¿Las consultas dinámicas de mysql con sql escapan son tan seguras como las declaraciones preparadas?

Tengo una aplicación que se beneficiaría enormemente al usar consultas dinámicas de mysql en combinación con mysql (mysqli) cadena de escape real. Si ejecutara todos los datos recibidos del usuario a través de mysql escape real, ¿sería tan seguro como usar las declaraciones preparadas de mysql?

Definitivamente no.

Si bien la pregunta en el título es ambigua y se puede interpretar como “Son consultas dinámicas de MySQL con cada parte está formateada correctamente …” y, por lo tanto, tiene una respuesta positiva, la pregunta en el cuerpo no es:

Si ejecutara todos los datos recibidos del usuario a través de mysql escape real, ¿sería tan seguro como usar las declaraciones preparadas de mysql?

Si miras más de cerca esta pregunta, entenderás que esto es solo una encarnación de citas mágicas . El verdadero propósito de esta característica deshonrada, desaprobada y eliminada es exactamente “ejecutar toda la entrada del usuario a través de escape”.
Todos saben hoy en día que las citas mágicas son malas. ¿Por qué respuesta positiva entonces?

De acuerdo, parece que necesita explicarse nuevamente, por qué el escape masivo es malo.

La raíz del problema es un delirio bastante fuerte, compartido por casi todos los usuarios de PHP:
Todos tienen la extraña creencia de que escapan haciendo algo con los “personajes peligrosos” (¿qué son?) Y los hacen “seguros” (¿cómo?). Huelga decir que no es más que una basura completa.

La verdad es:

  • Escapar no “desinfectar” nada.
  • Escapar no tiene nada que ver con las inyecciones.
  • Escapar no tiene nada que ver con la entrada del usuario.

Escapar es meramente un formato de cadena y nada más.
Cuando lo necesite, lo necesita a pesar de la posibilidad de inyección.
Cuando no lo necesite, no ayudará contra la inyección ni siquiera un poco.

Hablando de la diferencia con las declaraciones preparadas, hay al menos un problema (que ya se ha mencionado muchas veces bajo la etiqueta sql-injection ):
un código como este

 $clean = mysql_real_escape_string($_POST['some_dangerous_variable']); $query = "SELECT * FROM someTable WHERE somevalue = $clean"; 

NO lo ayudará contra la inyección.
Beause escapándose es solo una instalación de formateo de cadenas, no una herramienta de prevención de inyecciones de ninguna manera.
Imagínate.

Sin embargo, escapar tiene algo en común con las declaraciones preparadas:
Ambos no te garantizan la inyección si

  • lo está utilizando solo contra notoria “entrada de usuario”, no como una regla estricta para la construcción de CUALQUIER consulta, a pesar de la fuente de datos.
  • en caso de que necesite insertar no datos, sino un identificador o una palabra clave.

Para estar seguro en estas circunstancias, vea mi respuesta que explica cómo hacer una inyección FULL sql.

Para resumir: puede considerarse seguro solo si realiza 2 correcciones esenciales y una adicional a su statement inicial:

Si ejecuté todos los datos recibidos del usuario a través de mysql escape real y siempre lo adjunto entre comillas (y, como mencionó mysqli_set_charset() , mysqli_set_charset() se usa para hacer que mysqli_real_escape string () realmente lo haga (en una ocasión tan rara de usar algunos encoding impar como GBK)) ¿sería tan seguro como usar declaraciones preparadas de mysql?

Siguiendo estas reglas, sí, sería tan seguro como las declaraciones nativas preparadas.

Sí, pero un sí calificado.

Necesita escaparse correctamente al 100% de la entrada. Y necesita establecer correctamente conjuntos de caracteres (si está utilizando la API C, necesita llamar a mysql_set_character_set() lugar de SET NAMES ). Si te pierdes una pequeña cosa, eres vulnerable. Entonces sí, siempre y cuando lo haga todo bien …

Y esa es la razón por la que mucha gente recomendará consultas preparadas. No porque sean más seguros. Pero porque son más indulgentes …

Creo que @ircmaxell lo entendió bien.

Como seguimiento, esté atento a este tipo de cosas.
Solía ​​hacerlo todo el tiempo:

  

Y cuando digo “solía hacerlo”, ¡lo que quiero decir es que finalmente me rendí y comencé a usar declaraciones preparadas!