¿Función de formatting vs parameters en escenarios de inyección sql?

Sé sobre los usos de los parameters en oraciones sql, pero solo por curiosidad es seguro usar la function Format para evitar inyecciones sql en lugar de usar parameters.

como esta muestra

sCustomer : string begin AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]); end; 

Eso probablemente sería seguro contra la inyección de SQL, suponiendo que QuotedStr funciona como se espera y no hay casos límite que puedan romperlo. (Lo cual de ninguna manera está garantizado. Como señaló Linas en un comentario, MySql le permite usar \' para escaping las comillas. Otros DBMS probablemente tengan capacidades similares. Un atacante con suficiente conocimiento teórico del sistema podría explotarlos. )

Sin embargo, incluso si QuotedStr fuera lo suficientemente bueno, es mejor usar parameters por un motivo diferente: el performance. Cuando separa los parameters de su consulta, puede terminar enviando exactamente el mismo código de consulta varias veces con diferentes parameters. Si lo hace, la database puede almacenar en caching gran parte del trabajo que realiza al calcular la consulta, por lo que su acceso a la database se vuelve más rápido. Eso no funciona (o al less no tan bien) cuando se mezclan los parameters en el código de consulta en sí.

Cada vez que crea una cadena de SQL al concatenar cadenas, existe la posibilidad de un ataque de inyección, sin importar qué tan seguro piense que es el acceso a esas cadenas. Por lo que usted sabe, alguien podría ejecutar su aplicación dentro de un depurador, poner un punto de interrupción en el resultado de QuotedStr() y modificar su contenido antes de permitir que Format() vea.

El uso de parameters SQL reales es la forma más segura de hacerlo. No solo evita las inyecciones, sino que también permite que el motor SQL decida la mejor forma de formatear los parameters según sus propias necesidades, de modo que no tenga que preocuparse por formatear los valores en su propio código, sino que funciona bien con types de letra fuertes. idiomas (como Delphi). Sin mencionar los beneficios de performance de poder preparar la statement de SQL en el lado del server antes de ejecutarla en el código, incluso varias veces, networkinguciendo drásticamente el tráfico entre el cliente y el server y aumentando el performance general.

 var sCustomer : string begin AdoSql.CommandText := 'Select SUM(value) result from invoices where customer=:Customer'; AdoSql.Prepanetworking := True; ... AdoSql.Parameters['Customer'].Value := sCustomer; AdoSql1.ExecSQL; ... AdoSql.Parameters['Customer'].Value := sCustomer; AdoSql1.ExecSQL; ... AdoSql.Prepanetworking := False; end; 

No, Format no ofrece security desde la inyección de SQL. No es diferente de la concatenación de cadenas ordinaria en ese sentido.

La parte del código en la pregunta que hace algo en contra de la inyección de SQL es la llamada a QuotedStr , que puede usar con o sin Format . Sin embargo, no es tan confiable como las consultas con parameters reales.

La única ventaja de Format en este context es que toda la plantilla de cadena está en un solo lugar, por lo que es less probable que obtenga un espaciado y una puntuación incorrectos de lo que sería si tuviera que build la cadena con sucesivas operaciones + , donde el SQL apóstrofes podrían perderse entre los apóstrofos Delphi.