sql >> Base de Datos >  >> RDS >> Mysql

Reemplazo de funciones mysql_* con PDO y declaraciones preparadas

Gracias por la interesante pregunta. Aquí tienes:

Se escapa de personajes peligrosos,

Su concepto es totalmente erróneo.
De hecho, los "caracteres peligrosos" son un mito, no hay ninguno. Y mysql_real_escape_string se escapa, pero es simplemente un delimitador de cadena . A partir de esta definición, puede concluir sus limitaciones:solo funciona para cadenas .

sin embargo, sigue siendo vulnerable a otros ataques que pueden contener caracteres seguros pero que pueden ser perjudiciales para mostrar datos o, en algunos casos, para modificar o eliminar datos de forma malintencionada.

Estás mezclando aquí todo.
Hablando de base de datos,

  • para las cadenas, NO es vulnerable. Mientras sus cadenas estén entrecomilladas y escapadas, no pueden "modificar o eliminar datos malintencionadamente".*
  • para el otro tipo de datosdata - sí, es inútil . Pero no porque sea algo "inseguro" sino simplemente por un uso inadecuado.

En cuanto a la visualización de datos, supongo que es offtopic en la pregunta relacionada con PDO, ya que PDO tampoco tiene nada que ver con la visualización de datos.

escapando de la entrada del usuario

^^^ ¡Otro engaño a tener en cuenta!

  • la entrada de un usuario no tiene absolutamente nada que ver con escapar . Como puede aprender de la definición anterior, debe escapar de las cadenas, no de la "entrada del usuario". Entonces, de nuevo:

    • tiene cadenas de escape, sin importar su origen
    • es inútil escapar de otros tipos de datos, sin importar la fuente.

¿Entendió el punto?
Ahora, espero que comprenda las limitaciones de escapar, así como el concepto erróneo de "personajes peligrosos".

Tengo entendido que el uso de PDO/declaraciones preparadas es mucho más seguro

No realmente.
De hecho, hay cuatro diferentes partes de consulta que podemos agregarle dinámicamente:

  • una cadena
  • un número
  • un identificador
  • una palabra clave de sintaxis.

entonces, puede ver que escapar cubre solo un problema. (pero, por supuesto, si trata los números como cadenas (entre comillas), cuando corresponda , también puedes hacerlos seguros)

mientras que las declaraciones preparadas cubren - ugh - ¡2 problemas completos! Un gran problema;-)

Para los otros 2 problemas, vea mi respuesta anterior, En PHP, cuando envío cadenas a la base de datos, ¿debo ocuparme de los caracteres ilegales usando htmlspecialchars() o usar una expresión regular?

Ahora, los nombres de las funciones son diferentes, por lo que ya no funcionarán mysql_query, mysql_fetch_array, mysql_num_rows, etc.

Ese es otro, grave engaño de los usuarios de PHP , un desastre natural, una catástrofe:

Incluso cuando se utiliza el controlador mysql antiguo, nunca se deben usar las funciones API básicas en su código! ¡Uno tiene que ponerlos en alguna función de biblioteca para el uso diario! (No como un rito mágico, sino solo para hacer el código más corto, menos repetitivo, a prueba de errores, más consistente y legible).

¡Lo mismo ocurre con la DOP!

Ahora continúa con tu pregunta de nuevo.

pero al usarlos, ¿se elimina la necesidad de usar algo como mysql_real_escape_string?

SÍ.

Pero creo que esta es más o menos la idea de lo que se debe hacer para obtener un usuario de una base de datos

No para obtener, sino para agregar cualquier dato a la consulta !

tienes que dar una longitud después de PDO:PARAM_STR si no me equivoco

Puedes, pero no tienes que hacerlo.

Ahora, ¿todo esto es seguro?

En términos de seguridad de la base de datos, simplemente no hay puntos débiles en este código. Nada que asegurar aquí.

para la seguridad de visualización:simplemente busque en este sitio el XSS palabra clave.

Espero arrojar algo de luz sobre el asunto.

Por cierto, para las inserciones largas, puede hacer uso de la función que escribí algún día, Insertar/actualizar función auxiliar usando PDO

Sin embargo, no estoy usando declaraciones preparadas en este momento, ya que prefiero mis marcadores de posición elaborados en casa sobre ellos, utilizando una biblioteca Mencioné arriba. Entonces, para contrarrestar el código publicado por riha a continuación, sería tan corto como estas 2 líneas:

$sql  = 'SELECT * FROM `users` WHERE `name`=?s AND `type`=?s AND `active`=?i';
$data = $db->getRow($sql,$_GET['name'],'admin',1);

Pero, por supuesto, también puede tener el mismo código usando declaraciones preparadas.

* (yes I am aware of the Schiflett's scaring tales)