Pregunta

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

Por ejemplo, tengo una variedad de empleados:

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

y necesito terminar con una serie de cadenas, como esta:

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

Estoy mirando un código que crea las instrucciones de inserción con String.Format, pero eso no se siente bien. Pensé en usar SqlCommand (con la esperanza de hacer algo como esto ), pero no ofrece una forma de combinar el texto del comando con los parámetros.

¿Es suficiente reemplazar las comillas simples y construir una cadena?

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

¿Qué debería preocuparme al hacer esto? Los datos de origen son bastante seguros, pero no quiero hacer demasiadas suposiciones.

EDITAR: Solo quiero señalar que en este caso, no tengo una conexión 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 ()

¿Fue útil?

Solución

Usar comandos parametrizados. Pase los parámetros a su servidor remoto también, y haga que llame a SQL Server, manteniendo la distinción entre el propio SQL y los valores de los parámetros.

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

Otros consejos

Cree su objeto 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();

Repare su función de reemplazo de comillas de esta manera:

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

¡Salud!

Hmm. Estoy de acuerdo con todos los demás en que debería usar consultas parametrizadas y lo dejaré así. Pero, ¿cómo va a pasar estas declaraciones SQL a su servidor remoto? ¿Tiene algún tipo de servicio, como un servicio web que acepte y ejecute comandos SQL arbitrarios o su aplicación cliente golpeará la base de datos directamente?

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 Cade recomienda 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.

Para evitar la inyección, debe enviar los datos al servidor remoto (tal vez en XML) y luego en el servidor remoto, los datos deben volver a convertirse a los tipos de datos apropiados y utilizarse en consultas parametrizadas o procesos almacenados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top