2008-11-15 13 views
10

Estoy usando C# y .NET 3.5. Necesito generar y almacenar algunas instrucciones de inserción de T-SQL que se ejecutarán más adelante en un servidor remoto.Creando sentencias SQL seguras como cadenas

Por ejemplo, tengo una serie de empleados:

new Employee[] 
{ 
    new Employee { ID = 5, Name = "Frank Grimes" }, 
    new Employee { ID = 6, Name = "Tim O'Reilly" } 
} 

y necesito terminar con una matriz de cadenas, como esto:

"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')", 
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')" 

estoy mirando algo de código que crea las instrucciones de inserción con String.Format, pero eso no se siente bien. Consideré usar SqlCommand (esperando hacer something like this), pero no ofrece una manera de combinar el texto de comando con los parámetros.

¿Basta con reemplazar comillas simples y construir una cadena?

string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')", 
    employee.ID, 
    replaceQuotes(employee.Name) 
    ); 

¿De qué debería preocuparme cuando hago esto? La fuente de datos es bastante segura, pero no quiero hacer demasiadas suposiciones.

EDITAR: Solo quiero señalar que en este caso, no tengo una SqlConnection ni ninguna forma de conectarme directamente a SQL Server. Esta aplicación en particular necesita generar sentencias SQL y ponerlas en cola para que se ejecuten en otro lugar; de lo contrario, estaría usando SqlCommand.Parameters.AddWithValue()

+0

AddWithValue es genial (lo uso a menudo), PERO puede sufrir la conversión de tipo implícita incorrecta si no se usa con cuidado. –

Respuesta

6

Use comandos parametrizados. Pase también los parámetros a su servidor remoto y consígalo para llamar a SQL Server, manteniendo la distinción entre el SQL mismo y los valores de los parámetros.

Siempre y cuando nunca mezcles datos de tratamiento como código, deberías estar bien.

+0

Ahora me voy a la cama, en realidad. Predica mañana por la mañana 10.30-11.30, ¡así que tienes garantizado un buen crack en el látigo! ;) –

+0

¿Predicación? ¿Hay grabaciones? – tofutim

+0

@tofutim: No es que yo sepa. –

17

crear el objeto de SqlCommand así:

SqlCommand cmd = new SqlCommand(
     "INSERT INTO Employees (id, name) VALUES (@id, @name)", conn); 

SqlParameter param = new SqlParameter(); 
param.ParameterName = "@id"; 
param.Value   = employee.ID; 

cmd.Parameters.Add(param); 

param = new SqlParameter(); 
param.ParameterName = "@name"; 
param.Value   = employee.Name; 

cmd.Parameters.Add(param); 

cmd.ExecuteNonQuery(); 
+5

Usando "cmd.AddWithValue (" @ id ", employee.ID);" es mucho más terser. –

+0

Lo recibo de vez en cuando y lo recibí en mi respuesta a este también. –

+0

Brad Wilson: Se necesita un ".Parameters" adicional: 'cmd.Parameters.AddWithValue (" @ id ", employee.ID);' –

0

para evitar la inyección, es necesario enviar los datos al servidor remoto (tal vez en XML) y luego en el servidor remoto, los datos deben convertirse de nuevo para adecuar los tipos de datos y usarlos en consultas parametrizadas o procesos almacenados.

1

Hmm Estoy de acuerdo con todos los demás en que debería usar consultas parametrizadas y lo dejo ahí. Pero, ¿cómo vas a pasar estas sentencias sql a tu servidor remoto? ¿Tiene algún tipo de servicio como un servicio web que aceptará y ejecutará comandos Sql arbitrarios o su aplicación cliente va a llegar directamente a la base de datos?

Si está pasando por algún tipo de proxy, no importa cuánto desinfecte sus datos en el cliente, un hacker podría omitir su aplicación y acceder al servicio. En ese caso, haga lo que recomienda Cade y pase los datos como XML, por ejemplo, o el formato que elija (JSON, Binario, etc.). Luego, cree su SQL justo antes de ejecutar el comando.

4

arreglar su reemplazar comillas funcionan de esta manera:

void string replaceQuotes(string value) { 
    string tmp = value; 
    tmp = tmp.Replace("'", "''"); 
    return tmp; 
} 

Salud!

+2

Es mucho más fácil usar los parámetros, piense en todos los caracteres que se deben escapar. Y también esto no es seguro para inyección SQL. –

+0

@ KarelFrajták: ¿Cómo se pueden usar los parámetros cuando los comandos formateados solo se ejecutarán más tarde (presumiblemente, después de que la ejecución del código C# haya finalizado), como se describe en la pregunta? –

+0

@ O.R.Mapper, en ese caso, pondría en cola las instrucciones y un diccionario con los nombres y valores de los parámetros. –

Cuestiones relacionadas