php ¿Son las declaraciones preparadas PDO suficientes para evitar la inyección SQL?




3 Answers

Las declaraciones preparadas / consultas parametrizadas son generalmente suficientes para evitar la inyección de primer orden en esa declaración * . Si usa un sql dinámico sin comprobar en cualquier otra parte de su aplicación, todavía es vulnerable a la inyección de segundo orden .

La inyección de segundo orden significa que los datos se han pasado por la base de datos una vez antes de ser incluidos en una consulta, y es mucho más difícil de lograr. AFAIK, casi nunca se ven ataques de 2º orden diseñados con ingeniería real, ya que usualmente es más fácil para los atacantes hacer ingeniería social, pero a veces surgen errores de 2º orden debido a personajes extra benignos o similares.

Puede realizar un ataque de inyección de segundo orden cuando puede hacer que un valor se almacene en una base de datos que luego se usa como literal en una consulta. Como ejemplo, supongamos que ingresa la siguiente información como su nuevo nombre de usuario al crear una cuenta en un sitio web (asumiendo MySQL DB para esta pregunta):

' + (SELECT UserName + '_' + Password FROM Users LIMIT 1) + '

Si no hay otras restricciones en el nombre de usuario, una declaración preparada aún se asegurará de que la consulta incrustada anterior no se ejecute en el momento de la inserción, y almacene el valor correctamente en la base de datos. Sin embargo, imagine que más tarde la aplicación recupera su nombre de usuario de la base de datos y utiliza la concatenación de cadenas para incluir ese valor en una nueva consulta. Es posible que pueda ver la contraseña de otra persona. Dado que los primeros nombres en la tabla de usuarios tienden a ser administradores, es posible que también haya regalado la granja de servidores. (También tenga en cuenta: ¡esta es una razón más para no almacenar contraseñas en texto plano!)

Vemos, entonces, que las declaraciones preparadas son suficientes para una sola consulta, pero por sí mismas no son suficientes para proteger contra los ataques de inyección de SQL en toda la aplicación, ya que carecen de un mecanismo para imponer que todo el acceso a una base de datos dentro de la aplicación lo use. código de seguridad Sin embargo, se utiliza como parte de un buen diseño de la aplicación, que puede incluir prácticas como la revisión de código o el análisis estático, o el uso de un ORM, una capa de datos o una capa de servicio que limite las sentencias preparadas en sql dinámico: la herramienta principal para resolver la Inyección de SQL. problema. Si sigue buenos principios de diseño de aplicaciones, de manera que su acceso a los datos está separado del resto de su programa, es fácil hacer cumplir o auditar que cada consulta utiliza correctamente la parametrización. En este caso, la inyección de sql (tanto de primer como de segundo orden) se evita por completo.

* Resulta que MySql / PHP son (bueno, eran) tontos acerca del manejo de parámetros cuando se utilizan caracteres anchos, y todavía hay un caso raro descrito en la otra respuesta altamente votada aquí que puede permitir que la inyección se deslice a través de un parámetro consulta.

php security pdo sql-injection

Digamos que tengo un código como este:

$dbh = new PDO("blahblah");

$stmt = $dbh->prepare('SELECT * FROM users where username = :username');
$stmt->execute( array(':username' => $_REQUEST['username']) );

La documentación de la DOP dice:

Los parámetros para las declaraciones preparadas no necesitan ser citados; El conductor lo maneja por ti.

¿Es realmente todo lo que necesito hacer para evitar las inyecciones de SQL? ¿Es realmente tan fácil?

Puedes asumir MySQL si hace una diferencia. Además, solo tengo curiosidad por el uso de declaraciones preparadas contra la inyección de SQL. En este contexto, no me importa XSS u otras posibles vulnerabilidades.




Sí, es suficiente. La forma en que funcionan los ataques de tipo de inyección es obtener un intérprete (la base de datos) para evaluar algo, que debería haber sido información, como si fuera un código. Esto solo es posible si mezcla código y datos en el mismo medio (por ejemplo, cuando construye una consulta como una cadena).

Las consultas parametrizadas funcionan al enviar el código y los datos por separado, por lo que nunca sería posible encontrar un agujero en eso.

Sin embargo, todavía puedes ser vulnerable a otros ataques de tipo inyección. Por ejemplo, si usa los datos en una página HTML, podría estar sujeto a ataques de tipo XSS.




Personalmente, siempre ejecutaría algún tipo de saneamiento en los datos primero, ya que nunca se puede confiar en la entrada del usuario, sin embargo, al usar marcadores de posición / parámetros, los datos ingresados ​​se envían al servidor por separado a la declaración de SQL y luego se unen. La clave aquí es que esto une los datos proporcionados a un tipo específico y un uso específico y elimina cualquier oportunidad de cambiar la lógica de la declaración SQL.






Related