c# sql vb.net ado.net sql-injection

c# - ¿Cómo puedo agregar una entrada proporcionada por el usuario a una declaración SQL?



vb.net ado.net (2)

Código de ejemplo de VB.NET

Este es el código de ejemplo para la respuesta wiki en vb.net , suponiendo que Option Strict On y Option Infer On .

INSERTAR

Dim sql = "INSERT INTO myTable (myField1, myField2) " & "VALUES (@someValue, @someOtherValue);" Using cmd As New SqlCommand(sql, myDbConnection) cmd.Parameters.AddWithValue("@someValue", someVariable) cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text) cmd.ExecuteNonQuery() End Using

ACTUALIZAR

Dim sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;" '' see above, same as INSERT

SELECCIONAR

Dim sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;" Using cmd As New SqlCommand(sql, myDbConnection) cmd.Parameters.AddWithValue("@someValue", someVariable) Using reader = cmd.ExecuteReader() '' ... End Using '' Alternatively: Dim result = cmd.ExecuteScalar() '' if you are only interested in one value of one row. End Using

Estoy tratando de crear una declaración SQL utilizando datos proporcionados por el usuario. Yo uso un código similar a esto en C #:

var sql = "INSERT INTO myTable (myField1, myField2) " + "VALUES (''" + someVariable + "'', ''" + someTextBox.Text + "'');"; var cmd = new SqlCommand(sql, myDbConnection); cmd.ExecuteNonQuery();

y esto en VB.NET:

Dim sql = "INSERT INTO myTable (myField1, myField2) " & "VALUES (''" & someVariable & "'', ''" & someTextBox.Text & "'');" Dim cmd As New SqlCommand(sql, myDbConnection) cmd.ExecuteNonQuery()

Sin embargo,

  • esto falla cuando la entrada del usuario contiene comillas simples (por ejemplo, O''Brien ),
  • Parece que no puedo obtener el formato correcto al insertar valores DateTime y
  • la gente sigue diciéndome que no debería hacer esto debido a la "inyección SQL".

¿Cómo lo hago "de la manera correcta"?


Utiliza SQL parametrizado.

Ejemplos

(Estos ejemplos están en C #, consulte a continuación la versión VB.NET).

Reemplace sus concatenaciones de cadenas con @... marcadores de posición y, luego, agregue los valores a su SqlCommand. Puede elegir el nombre de los marcadores de posición libremente, solo asegúrese de que comiencen con el signo @ . Su ejemplo se vería así:

var sql = "INSERT INTO myTable (myField1, myField2) " + "VALUES (@someValue, @someOtherValue);"; using (var cmd = new SqlCommand(sql, myDbConnection)) { cmd.Parameters.AddWithValue("@someValue", someVariable); cmd.Parameters.AddWithValue("@someOtherValue", someTextBox.Text); cmd.ExecuteNonQuery(); }

El mismo patrón se usa para otros tipos de sentencias SQL:

var sql = "UPDATE myTable SET myField1 = @newValue WHERE myField2 = @someValue;"; // see above, same as INSERT

o

var sql = "SELECT myField1, myField2 FROM myTable WHERE myField3 = @someValue;"; using (var cmd = new SqlCommand(sql, myDbConnection)) { cmd.Parameters.AddWithValue("@someValue", someVariable); using (var reader = cmd.ExecuteReader()) { ... } // Alternatively: object result = cmd.ExecuteScalar(); // if you are only interested in one value of one row. }

Una advertencia: AddWithValue es un buen punto de partida y funciona bien en la mayoría de los casos. Sin embargo, el valor que pase debe coincidir exactamente con el tipo de datos del campo de base de datos correspondiente. De lo contrario, podría terminar en una situación en la que la conversión impide que su consulta use un índice . Tenga en cuenta que algunos tipos de datos de SQL Server, como char / varchar (sin la "n" precedente) o fecha no tienen un tipo de datos .NET correspondiente. En esos casos, se debe utilizar Add con el tipo de datos correcto .

¿Por qué debería hacer eso?

Otras bibliotecas de acceso a bases de datos

  • Si usa un OleDbCommand en lugar de un SqlCommand (por ejemplo, si está usando una base de datos de MS Access), use ? en lugar de @... como el marcador de posición en el SQL. En ese caso, el primer parámetro de AddWithValue es irrelevante; en su lugar, debe agregar los parámetros en el orden correcto. Lo mismo es cierto para OdbcCommand .

  • Entity Framework también admite consultas parametrizadas.