php - sentencias - qué tan seguras son las declaraciones preparadas de PDO
sentencias preparadas php mysqli (4)
Con respecto a las inyecciones SQL, creo que es lo más seguro que puede obtener, especialmente si usa constantes como PDO :: PARAM_INT.
Empecé a utilizar declaraciones preparadas por PDO no hace mucho tiempo, y, según tengo entendido, hace todo el escape / seguridad para usted.
por ejemplo, suponiendo que $ _POST [''title''] es un campo de formulario.
$title = $_POST[''title''];
$query = "insert into blog(userID, title) values (?, ?)"
$st = $sql->prepare($query);
$st->bindParam(1, $_SESSION[''user''][''userID''], PDO::PARAM_INT);
$st->bindParam(2, $title);
$st->execute();
¿Esto es realmente seguro? ¿Tengo que hacer algo más? ¿Qué más tengo que tomar en consideración?
Gracias.
Dado que se mencionó XSS, creo que también es bueno echar un vistazo al uso de cosas como esta clase de limpieza de entrada http://www.phpclasses.org/browse/package/2189.html para evitar ataques XSS.
Está a salvo de la inyección SQL.
Un par de cosas de las que NO es seguro:
- Denegación de servicio (lo que hace que se creen cantidades excesivas de filas)
- Ataques de secuencias de comandos entre sitios (si el título alguna vez se repite a otro usuario)
La seguridad es más que solo evitar la inyección de SQL.
Estrictamente hablando, en realidad no se necesita escaparse, porque el valor del parámetro nunca se interpola en la cadena de consulta.
La forma en que funcionan los parámetros de consulta es que la consulta se envía al servidor de la base de datos cuando se llama a prepare()
, y los valores de los parámetros se envían más tarde, cuando se llama a execute()
. Por lo tanto, se mantienen separados de la forma textual de la consulta. Nunca hay una oportunidad para inyección SQL (siempre que PDO::ATTR_EMULATE_PREPARES
sea falso).
Entonces sí, los parámetros de consulta lo ayudan a evitar esa forma de vulnerabilidad de seguridad.
¿Son 100% de prueba contra cualquier vulnerabilidad de seguridad? No claro que no. Como sabrá, un parámetro de consulta solo ocupa el lugar de un único valor literal en una expresión SQL. No puede hacer que un solo parámetro sustituya a una lista de valores, por ejemplo:
SELECT * FROM blog WHERE userid IN ( ? );
No puede usar un parámetro para hacer dinámicos los nombres de tabla o columnas:
SELECT * FROM blog ORDER BY ?;
No puede usar un parámetro para ningún otro tipo de sintaxis SQL:
SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;
Así que hay bastantes casos en los que tiene que manipular la consulta como una cadena, antes de la llamada a prepare()
. En estos casos, aún necesita escribir el código cuidadosamente para evitar la inyección de SQL.