Evitando la inyección de SQL sin parámetros

109

Tenemos otra discusión aquí en el trabajo sobre el uso de consultas sql parametrizadas en nuestro código. Tenemos dos lados en la discusión: yo y algunos otros que dicen que siempre deberíamos usar parámetros para protegernos de las inyecciones de sql y los otros chicos que no creen que sea necesario. En su lugar, quieren reemplazar apóstrofos simples con dos apóstrofes en todas las cadenas para evitar inyecciones de sql. Todas nuestras bases de datos ejecutan Sql Server 2005 o 2008 y nuestra base de código se ejecuta en .NET framework 2.0.

Déjame darte un ejemplo simple en C #:

Quiero que usemos esto:

string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe

Mientras que los otros chicos quieren hacer esto:

string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?

Donde la función SafeDBString se define de la siguiente manera:

string SafeDBString(string inputValue) 
{
    return "'" + inputValue.Replace("'", "''") + "'";
}

Ahora, siempre que usemos SafeDBString en todos los valores de cadena en nuestras consultas, deberíamos estar seguros. ¿Correcto?

Hay dos razones para utilizar la función SafeDBString. Primero, es la forma en que se ha hecho desde la edad de piedra, y segundo, es más fácil depurar las declaraciones sql ya que ve la consulta exacta que se ejecuta en la base de datos.

Por lo que entonces. Mi pregunta es si realmente es suficiente usar la función SafeDBString para evitar ataques de inyección SQL. He estado tratando de encontrar ejemplos de código que rompa esta medida de seguridad, pero no puedo encontrar ningún ejemplo de ello.

¿Hay alguien ahí fuera que pueda romper esto? ¿Como lo harias?

EDITAR: Para resumir las respuestas hasta ahora:

  • Nadie ha encontrado una manera de sortear SafeDBString en Sql Server 2005 o 2008 todavía. Eso es bueno, creo.
  • Varias respuestas señalaron que se obtiene una ganancia de rendimiento cuando se utilizan consultas parametrizadas. La razón es que los planes de consulta se pueden reutilizar.
  • También estamos de acuerdo en que el uso de consultas parametrizadas proporciona un código más legible que es más fácil de mantener.
  • Además, es más fácil usar siempre parámetros que usar varias versiones de SafeDBString, conversiones de cadena a número y conversiones de cadena a fecha.
  • Usando parámetros obtienes conversión automática de tipos, algo que es especialmente útil cuando estamos trabajando con fechas o números decimales.
  • Y finalmente: no intente hacer la seguridad usted mismo como escribió JulianR. Los proveedores de bases de datos gastan mucho tiempo y dinero en seguridad. No hay forma de que podamos hacerlo mejor y no hay razón por la que debamos intentar hacer su trabajo.

Entonces, aunque nadie pudo romper la seguridad simple de la función SafeDBString, obtuve muchos otros buenos argumentos. ¡Gracias!

Runa Grimstad
fuente
16
Tus colegas están muy, muy fuera de lugar. Desafíelos a encontrar una sola pieza de literatura que respalde su posición. El argumento ex neolithos es ridículo, las cosas cambian, solo una persona atrapada en la edad de piedra no lograría adaptarse.
Annakata
1
Bueno, al menos sus colegas se protegen contra UNA de las diferentes formas de pirateo ... ¿Están seguros de que eso es lo que hacen todas las consultas parametrizadas? (No soy ...)
Arjan Einbu
1
Cualquier vulnerabilidad no los convencerá. Si trae varias vulnerabilidades (que es lo que está pidiendo) y otros problemas y señala uno por uno que los parámetros resolverán ese problema y que su equipo tendría que escribir montañas de código para proporcionar una fracción de la funcionalidad, puede conquistarlos. Buena suerte.
Robert Gowland
3
Incluso sin comillas simples, aún puede romper su código con lógica. Intente usar el nombre de usuario "test OR 1 = 1" - ¡obtendrá todas las filas devueltas en lugar de solo la que tiene la prueba de nombre de usuario!
Puente
1
Suspiro. Realmente no entiendo cómo nos las arreglamos como industria para seguir tolerando este tipo de comportamiento poco profesional.
jeroenh

Respuestas:

83

Creo que la respuesta correcta es:

No intente hacer la seguridad usted mismo . Use cualquier biblioteca estándar de la industria confiable que esté disponible para lo que está tratando de hacer, en lugar de intentar hacerlo usted mismo. Cualesquiera sean las suposiciones que haga sobre la seguridad, pueden ser incorrectas. Por más seguro que parezca su propio enfoque (y, en el mejor de los casos, parece inestable), existe el riesgo de que esté pasando por alto algo y ¿realmente quiere arriesgarse cuando se trata de seguridad?

Utilice parámetros.

JulianR
fuente
Re "Utilice cualquier biblioteca estándar de confianza de la industria" - ¿puede recomendar una para .NET? ¿Quizás más de uno dependiendo de la base de datos: SQLServer, MySQL, PostgreSQL? He buscado un desinfectante de SQL pero sin mucha suerte, por lo que me he visto obligado a implementar el mío, lo mejor que puedo (que sin duda está lejos de ser infalible).
PSU
72

Y luego alguien va y usa "en lugar de". Los parámetros son, en mi opinión, la única forma segura de hacerlo.

También evita muchos problemas de i18n con fechas / números; que fecha es 01/02/03? A cuanto esta el 123,456? ¿Sus servidores (app-server y db-server) están de acuerdo entre sí?

Si el factor de riesgo no les convence, ¿qué tal el rendimiento? El RDBMS puede reutilizar el plan de consulta si usa parámetros, lo que ayuda al rendimiento. No puede hacer esto solo con la cuerda.

Marc Gravell
fuente
He probado los argumentos de formato y rendimiento, pero todavía no están convencidos.
Rune Grimstad
5
En realidad, el servidor sql puede reutilizar el plan de consulta tanto si utiliza parámetros como si no. Estoy de acuerdo con los otros argumentos, pero en la mayoría de los casos, el argumento de rendimiento para sql parametrizado ya no funciona.
tnyfst
1
@tnyfst: ¿puede reutilizar el plan de ejecución cuando la cadena de consulta cambia para cada combinación de valores de parámetros? No lo creí posible.
John Saunders
4
El plan de consulta se reutilizará si el texto de la consulta es IDÉNTICO a un texto de consulta anterior. Entonces, si envía la MISMA consulta EXACTAMENTE dos veces, se reutilizará. Sin embargo, si cambia incluso solo un espacio o una coma o algo, se deberá determinar un nuevo plan de consulta.
marc_s
1
@Marc: No estoy seguro de que estés en lo cierto. La huerística de almacenamiento en caché de los servidores SQL es un poco extraña. El analizador es capaz de identificar constantes en el texto y puede convertir la cadena SQL a uno de los parámetros de uso de forma artificial. A continuación, puede insertar en la caché el texto de esta nueva consulta parametrizada. SQL posterior similar puede encontrar su versión parametrizada coincidente en la caché. Sin embargo, las versiones parametrizadas no siempre se usan con las versiones originales de SQL almacenadas en caché, sospecho que SQL tiene un trillón de razones relacionadas con el rendimiento para elegir entre los dos enfoques.
AnthonyWJones
27

El argumento es un fracaso. Si logra encontrar una vulnerabilidad, sus compañeros de trabajo simplemente cambiarán la función SafeDBString para dar cuenta de ella y luego le pedirán que demuestre que es inseguro nuevamente.

Dado que las consultas parametrizadas son una mejor práctica de programación indiscutible, la carga de la prueba debería recaer en ellos para indicar por qué no están utilizando un método que sea más seguro y de mejor rendimiento.

Si el problema es reescribir todo el código heredado, el compromiso fácil sería usar consultas parametrizadas en todo el código nuevo y refactorizar el código antiguo para usarlas cuando se trabaja en ese código.

Supongo que el problema real es el orgullo y la terquedad, y no hay mucho más que puedas hacer al respecto.

Matthew Christensen
fuente
19

En primer lugar, su muestra para la versión "Reemplazar" es incorrecta. Debes poner apóstrofos alrededor del texto:

string sql = "SELECT * FROM Users WHERE Name='" + SafeDBString(name) & "'";
SqlCommand getUser = new SqlCommand(sql, connection);

Esa es otra cosa que los parámetros hacen por usted: no necesita preocuparse por si un valor debe estar entre comillas o no. Por supuesto, podría incorporar eso en la función, pero luego necesita agregar mucha complejidad a la función: cómo saber la diferencia entre 'NULL' como nulo y 'NULL' como solo una cadena, o entre un número y una cadena que simplemente contiene muchos dígitos. Es solo otra fuente de errores.

Otra cosa es el rendimiento: los planes de consulta parametrizados a menudo se almacenan en caché mejor que los planes concatenados, por lo que quizás le ahorre un paso al servidor al ejecutar la consulta.

Además, escapar de las comillas simples no es suficiente. Muchos productos de bases de datos permiten métodos alternativos para escapar de caracteres que un atacante podría aprovechar. En MySQL, por ejemplo, también puede escapar una comilla simple con una barra invertida. Y así, el siguiente valor de "nombre" haría explotar MySQL con solo la SafeDBString()función, porque cuando duplica la comilla simple, la primera todavía se escapa por la barra invertida, dejando la segunda "activa":

x \ 'O 1 = 1; -


Además, JulianR trae un buen punto a continuación: NUNCA intente hacer trabajo de seguridad usted mismo. Es muy fácil equivocarse en la programación de seguridad de formas sutiles que parecen funcionar, incluso con pruebas exhaustivas. Luego pasa el tiempo y un año después descubres que tu sistema se rompió hace seis meses y ni siquiera lo sabías hasta entonces.

Confíe siempre tanto como sea posible en las bibliotecas de seguridad proporcionadas para su plataforma. Serán escritos por personas que se dedican a crear códigos de seguridad, mucho mejor probados que lo que puede administrar y atendidos por el proveedor si se encuentra una vulnerabilidad.

Joel Coehoorn
fuente
5
La función de reemplazo agrega los apóstrofos
Rune Grimstad
5
Entonces es solo una fuente más de errores. ¿Cómo sabe la diferencia entre NULL como valor nulo y NULL como cadena de texto? ¿O entre una entrada numérica y una cadena que simplemente contiene dígitos?
Joel Coehoorn
Buen punto. Solo debe usar la función para cadenas y posiblemente fechas, por lo que debe tener cuidado. ¡Esa es una razón más para usar parámetros! ¡Hurra!
Runa Grimstad
10

Entonces yo diría:

1) ¿Por qué intentas volver a implementar algo que está integrado? está ahí, fácilmente disponible, fácil de usar y ya depurado a escala global. Si se encuentran errores en el futuro, se solucionarán y estarán disponibles para todos muy rápidamente sin que tenga que hacer nada.

2) ¿Qué procesos existen para garantizar que nunca se pierda una llamada a SafeDBString? Perderlo en un solo lugar podría generar una gran cantidad de problemas. ¿Cuánto vas a observar estas cosas y considerar cuánto esfuerzo desperdiciado es cuando la respuesta correcta aceptada es tan fácil de alcanzar?

3) ¿Qué tan seguro está de haber cubierto todos los vectores de ataque que Microsoft (el autor de la base de datos y la biblioteca de acceso) conoce en su implementación de SafeDBString ...

4) ¿Qué tan fácil es leer la estructura del sql? El ejemplo usa + concatenación, los parámetros son muy parecidos a string.Format, que es más legible.

Además, hay 2 formas de averiguar qué se ejecutó realmente: ejecute su propia función LogCommand, una función simple con sin preocupaciones de seguridad , o incluso mirar un rastreo de sql para averiguar lo que la base de datos cree que realmente está sucediendo.

Nuestra función LogCommand es simplemente:

    string LogCommand(SqlCommand cmd)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(cmd.CommandText);
        foreach (SqlParameter param in cmd.Parameters)
        {
            sb.Append(param.ToString());
            sb.Append(" = \"");
            sb.Append(param.Value.ToString());
            sb.AppendLine("\"");
        }
        return sb.ToString();
    }

Bien o mal, nos brinda la información que necesitamos sin problemas de seguridad.

Jim T
fuente
1
Probablemente tenga que lidiar con un grupo de antiguos programadores de VBSCRIPT que están acostumbrados a hacer de todo, incluidos XML y SQL, a través de la concatenación de cadenas. Serán personas a las que les asusta el uso de una API. No hay mucho que se pueda hacer con ellos, al menos nada humano.
John Saunders
1
+1 para el elemento n. ° 2, con la excepción de que tampoco hay forma de hacer cumplir los parámetros reales.
Joel Coehoorn
7

Con las consultas parametrizadas, obtiene más que protección contra la inyección de SQL. También obtiene un mejor potencial de almacenamiento en caché del plan de ejecución. Si usa el generador de perfiles de consultas del servidor sql, aún puede ver el 'sql exacto que se ejecuta en la base de datos', por lo que tampoco está perdiendo nada en términos de depuración de sus declaraciones sql.

Steve Willcock
fuente
MySQL también registra consultas parametrizadas con valores de parámetros interpolados en ellas.
Bill Karwin
5

He utilizado ambos enfoques para evitar ataques de inyección de SQL y definitivamente prefiero las consultas parametrizadas. Cuando he usado consultas concatenadas, he usado una función de biblioteca para escapar de las variables (como mysql_real_escape_string) y no estaría seguro de haber cubierto todo en una implementación propietaria (como parece que tú también lo estás).

RojoAzulCosa
fuente
2
+1 porque mysql_real_escape_string () escapa de \ x00, \ x1a, \ n \ r 'y ". También maneja problemas de juego de caracteres. ¡La función ingenua de los compañeros de trabajo del OP no hace nada de eso!
Bill Karwin
4

No puede realizar fácilmente ninguna verificación de tipo de la entrada del usuario sin utilizar parámetros.

Si usa las clases SQLCommand y SQLParameter para realizar sus llamadas a la base de datos, aún puede ver la consulta SQL que se está ejecutando. Mire la propiedad CommandText de SQLCommand.

Siempre soy un poco sospechoso del enfoque de roll-your-own para prevenir la inyección de SQL cuando las consultas parametrizadas son tan fáciles de usar. En segundo lugar, solo porque "siempre se ha hecho de esa manera" no significa que sea la forma correcta de hacerlo.

Tim Scarborough
fuente
3

Esto solo es seguro si tiene la garantía de que va a pasar una cadena.

¿Qué pasa si no está pasando una cadena en algún momento? ¿Qué pasa si pasa solo un número?

http://www.mywebsite.com/profile/?id=7;DROP DATABASE DB

Finalmente se convertiría en:

SELECT * FROM DB WHERE Id = 7;DROP DATABASE DB
Joshcomley
fuente
Es una cadena o un número. Una cadena se escapa con SafeDbString. Un número es un Int32 y no puede eliminar bases de datos.
Andomar
Los números son más fáciles de manejar. Simplemente convierta el parámetro en int / float / lo que sea antes de usarlo en la consulta. El problema es cuando debe aceptar datos de cadena.
Rune Grimstad
Andomar: si solo está construyendo una declaración SQL a mano, entonces su "tipo" previsto no importa, puede inyectar SQL con un número muy, muy fácilmente. Rune: creo que esto depende demasiado del desarrollador individual para recordar todos los matices de resolver manualmente la inyección SQL. Si solo dice "usar parámetros" es muy simple y no pueden fallar.
Joshcomley
@Andomar: ¿Qué pasa con NULL? ¿O cadenas que parecen números?
Joel Coehoorn
2

Usaría procedimientos o funciones almacenados para todo, por lo que la pregunta no surgiría.

Donde tengo que poner SQL en código, uso parámetros, que es lo único que tiene sentido. Recuérdeles a los disidentes que hay piratas informáticos más inteligentes que ellos y con mejores incentivos para romper el código que intenta burlarlos. Usando parámetros, simplemente no es posible, y no es difícil.

John Saunders
fuente
Ok, ¿cómo hacer una inyección SQL usando parámetros?
John Saunders
@Saunders: El paso 1 es encontrar un error de desbordamiento de búfer en la funcionalidad de manejo de parámetros de su base de datos.
Brian
2
¿Encontraste uno todavía? ¿En una base de datos comercial que está siendo atacada por cientos de miles de piratas informáticos a diario? ¿Uno hecho por una empresa de software que se sabe que tiene mucho dinero? Podría citar la demanda por su nombre si esto fuera posible.
John Saunders
1
Por supuesto, si SPROC usa la concatenación y EXEC (en lugar de sp_ExecuteSQL) estás de nuevo en problemas ... (Lo he visto mal demasiadas veces para descartarlo ...)
Marc Gravell
2

Muy de acuerdo en las cuestiones de seguridad.
Otra razón para utilizar parámetros es la eficiencia.

Las bases de datos siempre compilarán su consulta y la almacenarán en caché, luego volverán a utilizar la consulta en caché (que obviamente es más rápida para solicitudes posteriores). Si usa parámetros, incluso si usa parámetros diferentes, la base de datos reutilizará su consulta almacenada en caché ya que coincide con la cadena SQL antes de vincular los parámetros.

Sin embargo, si no vincula los parámetros, la cadena SQL cambia en cada solicitud (que tiene parámetros diferentes) y nunca coincidirá con lo que está en su caché.

Grebas de Darren
fuente
2

Por las razones ya dadas, los parámetros son una muy buena idea. Pero odiamos usarlos porque crear el parámetro y asignar su nombre a una variable para su uso posterior en una consulta es un desastre de triple indirección.

La siguiente clase envuelve el generador de cadenas que utilizará habitualmente para crear solicitudes SQL. Le permite escribir consultas paramaterizadas sin tener que crear un parámetro , para que pueda concentrarse en SQL. Tu código se verá así ...

var bldr = new SqlBuilder( myCommand );
bldr.Append("SELECT * FROM CUSTOMERS WHERE ID = ").Value(myId, SqlDbType.Int);
//or
bldr.Append("SELECT * FROM CUSTOMERS WHERE NAME LIKE ").FuzzyValue(myName, SqlDbType.NVarChar);
myCommand.CommandText = bldr.ToString();

La legibilidad del código, espero que esté de acuerdo, ha mejorado mucho y el resultado es una consulta parametrizada adecuada.

La clase se ve así ...

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace myNamespace
{
    /// <summary>
    /// Pour le confort et le bonheur, cette classe remplace StringBuilder pour la construction
    /// des requêtes SQL, avec l'avantage qu'elle gère la création des paramètres via la méthode
    /// Value().
    /// </summary>
    public class SqlBuilder
    {
        private StringBuilder _rq;
        private SqlCommand _cmd;
        private int _seq;
        public SqlBuilder(SqlCommand cmd)
        {
            _rq = new StringBuilder();
            _cmd = cmd;
            _seq = 0;
        }
        //Les autres surcharges de StringBuilder peuvent être implémenté ici de la même façon, au besoin.
        public SqlBuilder Append(String str)
        {
            _rq.Append(str);
            return this;
        }
        /// <summary>
        /// Ajoute une valeur runtime à la requête, via un paramètre.
        /// </summary>
        /// <param name="value">La valeur à renseigner dans la requête</param>
        /// <param name="type">Le DBType à utiliser pour la création du paramètre. Se référer au type de la colonne cible.</param>
        public SqlBuilder Value(Object value, SqlDbType type)
        {
            //get param name
            string paramName = "@SqlBuilderParam" + _seq++;
            //append condition to query
            _rq.Append(paramName);
            _cmd.Parameters.Add(paramName, type).Value = value;
            return this;
        }
        public SqlBuilder FuzzyValue(Object value, SqlDbType type)
        {
            //get param name
            string paramName = "@SqlBuilderParam" + _seq++;
            //append condition to query
            _rq.Append("'%' + " + paramName + " + '%'");
            _cmd.Parameters.Add(paramName, type).Value = value;
            return this; 
        }

        public override string ToString()
        {
            return _rq.ToString();
        }
    }
}
bbsimonbb
fuente
1

Desde el muy poco tiempo que tuve para investigar los problemas de inyección de SQL, puedo ver que hacer que un valor sea 'seguro' también significa que está cerrando la puerta a situaciones en las que realmente podría querer apóstrofos en sus datos, ¿qué pasa con el nombre de alguien? , por ejemplo, O'Reilly.

Eso deja parámetros y procedimientos almacenados.

Y sí, siempre debe intentar implementar el código de la mejor manera que conoce ahora, no solo cómo se ha hecho siempre.

quamrana
fuente
Los apóstrofos dobles serán traducidos por el servidor SQL en un solo apóstrofo, por lo que O'Reilly se traduciría en Name = 'O''Reilly'
Rune Grimstad
Entonces, ¿existe una función correspondiente para eliminar apóstrofos cuando el usuario quiere ver sus datos?
quamrana
No hay necesidad. La secuencia de escape permite al analizador ver una comilla simple en lugar del final de la cadena. Mientras analiza, se ve ''como un literal ', por lo que su cadena se verá internamente como la secuencia de caracteres O'Reilly. Eso es lo que la base de datos almacenará, recuperará, comparará, etc. Si desea mostrar al usuario sus datos después de haberlos escapado, guarde una copia de la cadena sin escape en el lado de la aplicación.
cHao
1

Aquí hay un par de artículos que pueden resultarle útiles para convencer a sus compañeros de trabajo.

http://www.sommarskog.se/dynamic_sql.html

http://unixwiz.net/techtips/sql-injection.html

Personalmente, prefiero no permitir que ningún código dinámico toque mi base de datos, requiriendo que todos los contactos sean a través de sps (y no uno que use SQl dinámico). Esto significa que no se puede hacer nada excepto lo que he dado permiso a los usuarios para hacer y que los usuarios internos (excepto los pocos con acceso de producción para fines de administración) no pueden acceder directamente a mis tablas y crear estragos, robar datos o cometer fraude. Si ejecuta una aplicación financiera, esta es la forma más segura de hacerlo.

HLGEM
fuente
1

Puede romperse, sin embargo, los medios dependen de las versiones / parches exactos, etc.

Uno que ya se ha mencionado es el error de desbordamiento / truncamiento que se puede aprovechar.

Otro medio futuro sería encontrar errores similares a otras bases de datos; por ejemplo, la pila MySQL / PHP sufrió un problema de escape porque ciertas secuencias UTF8 podrían usarse para manipular la función de reemplazo; la función de reemplazo sería engañada para introducir los caracteres de inyección.

Al final del día, el mecanismo de seguridad de reemplazo se basa en la funcionalidad esperada pero no prevista . Dado que la funcionalidad no era el propósito previsto del código, existe una alta probabilidad de que alguna peculiaridad descubierta rompa la funcionalidad esperada.

Si tiene una gran cantidad de código heredado, el método de reemplazo podría usarse como una solución provisional para evitar una reescritura y pruebas prolongadas. Si está escribiendo un código nuevo, no hay excusa.

David
fuente
1

Utilice siempre consultas parametrizadas siempre que sea posible. A veces, incluso una entrada simple sin el uso de caracteres extraños ya puede crear una inyección SQL si no se identifica como entrada para un campo en la base de datos.

Así que deje que la base de datos haga su trabajo de identificar la entrada en sí misma, sin mencionar que también ahorra muchos problemas cuando realmente necesita insertar caracteres extraños que de otro modo se escaparían o cambiarían. Incluso puede ahorrar algo de tiempo de ejecución valioso al final por no tener que calcular la entrada.

VulstaR
fuente
1

No vi ninguna otra respuesta que aborde este lado del 'por qué hacerlo usted mismo es malo', pero considere un ataque de truncamiento de SQL .

También existe la función QUOTENAMET-SQL que puede ser útil si no puede convencerlos de que usen params. Captura muchas (¿todas?) De las preocupaciones de qoute escapadas.

JasonRShaver
fuente
1

2 años después , reciví ... Cualquiera que encuentre los parámetros un dolor es bienvenido a probar mi extensión VS, QueryFirst . Edita su solicitud en un archivo .sql real (Validación, Intellisense). Para agregar un parámetro, simplemente escríbalo directamente en su SQL, comenzando con '@'. Cuando guarde el archivo, QueryFirst generará clases contenedoras para permitirle ejecutar la consulta y acceder a los resultados. Buscará el tipo de base de datos de su parámetro y lo asignará a un tipo .net, que encontrará como entrada a los métodos Execute () generados.No podría ser más simple. Hacerlo de la manera correcta es radicalmente más rápido y fácil que hacerlo de cualquier otra manera, y crear una vulnerabilidad de inyección SQL se vuelve imposible, o al menos perversamente difícil. Hay otras ventajas extraordinarias, como poder eliminar columnas en su base de datos y ver inmediatamente errores de compilación en su aplicación.

descargo de responsabilidad legal: escribí QueryFirst

bbsimonbb
fuente
0

A continuación, se muestran algunas razones para utilizar consultas con parámetros:

  1. Seguridad: la capa de acceso a la base de datos sabe cómo eliminar o escapar de los elementos que no están permitidos en los datos.
  2. Separación de preocupaciones: mi código no es responsable de transformar los datos en un formato que le guste a la base de datos.
  3. Sin redundancia: no necesito incluir un ensamblado o una clase en cada proyecto que formatea / escapa esta base de datos; está integrado en la biblioteca de clases.
Señor de poder
fuente
0

Hubo pocas vulnerabilidades (no recuerdo qué base de datos era) relacionadas con el desbordamiento del búfer de la declaración SQL.

Lo que quiero decir es que SQL-Injection es más que simplemente "escapar de la cita", y no tienes idea de lo que vendrá después.

Dennis C
fuente
0

Otra consideración importante es realizar un seguimiento de los datos con y sin escape. Hay toneladas y toneladas de aplicaciones, web y de otro tipo, que no parecen realizar un seguimiento adecuado de cuándo los datos son Unicode sin formato, y codificados, HTML formateados, etc. Es obvio que será difícil hacer un seguimiento de qué cadenas están'' codificadas y cuáles no.

También es un problema cuando terminas cambiando el tipo de alguna variable; quizás solía ser un número entero, pero ahora es una cadena. Ahora tienes un problema.

Paul Fisher
fuente