2010-07-09 15 views
13

Principiante aquí:¿Qué está pasando los parámetros a SQL y por qué lo necesito?

En este answer a mi pregunta de cómo insertar datos en SQL Server, mencionó pasar parámetros en lugar de concatenación de cadenas como la que tengo actualmente.

¿Es esto realmente necesario para la seguridad? Si es así, ¿qué es exactamente pasar los parámetros? Cuando lo busco en google obtengo mucho acerca de los procedimientos almacenados. Es eso lo que quiero, no sé sobre procedimientos almacenados ... todavía.

Si puede orientarme en la dirección correcta, lo agradecería.

Gracias.

EDIT:

autorización, aquí es lo que tengo. Parece actualizar la base de datos correctamente y eventualmente cambiaré las entradas codificadas a las entradas de una etiqueta. Por favor, confirme si la forma en que lo hice no es vulnerable a ninguna inyección sql o pirateo.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.Security; 

using System.Data; 
using System.Data.Sql; 
using System.Data.SqlClient; 



public partial class Stats : System.Web.UI.Page 
{ 

    public SqlDataReader DataReader; 
    public SqlCommand Command; 
    string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES (@UID, @CL, @LL, @HL);"); 
    //string queryString = ("INSERT INTO UserData (UserProfileID, ConfidenceLevel, LoveLevel, HappinessLevel) VALUES ('a051fc1b-4f51-485b-a07d-0f378528974e', 2, 2, 2);"); 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     LabelUserID.Text = Membership.GetUser().ProviderUserKey.ToString(); 

    } 

    protected void Button1_Click(object sender, EventArgs e) 
    { 

     //connect to database 
     MySqlConnection database = new MySqlConnection(); 
     database.CreateConn(); 

     //create command object 
     Command = new SqlCommand(queryString, database.Connection); 

     //add parameters. used to prevent sql injection 
     Command.Parameters.Add("@UID", SqlDbType.UniqueIdentifier); 
     Command.Parameters["@UID"].Value = Membership.GetUser().ProviderUserKey; 

     Command.Parameters.Add("@CL", SqlDbType.Int); 
     Command.Parameters["@CL"].Value = 9; 

     Command.Parameters.Add("@LL", SqlDbType.Int); 
     Command.Parameters["@LL"].Value = 9; 

     Command.Parameters.Add("@HL", SqlDbType.Int); 
     Command.Parameters["@HL"].Value = 9; 

     Command.ExecuteNonQuery(); 


    } 

} 
+5

Mi momento de mayor orgullo: http://stackoverflow.com/questions/332365/xkcd-sql-injection-please-explain/332367 – Will

+0

@Will - Me encantan las pequeñas Bobby Tables. Ranks justo allí con su tira sobre Gotos. –

+0

@Will: Nice .... –

Respuesta

16

Pasar los parámetros a SQL le ahorra tener que crear una cadena SQL dinámica.

Crear sentencias SQL dinámicas es un GRAN riesgo de seguridad porque las personas pueden inyectar su propio código SQL en su aplicación, posiblemente ejecutando comandos no deseados contra sus datos.

hay algunos buenos ejemplos de posibles ataques de inyección SQL en:

SQL Injection Attacks by Example

Hay dos maneras de pasar parámetros a las sentencias SQL. Una es usar procedimientos almacenados como usted mencionó. El otro es usar consultas parametrizadas (que es en realidad lo que prefiero).

una consulta parametrizada es en realidad bastante fácil en .NET:

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    SqlCommand command = 
     new SqlCommand("SELECT * FROM Users WHERE Username = @Username", conn); 

    command.Parameters.Add(new SqlParameter("@Username", "Justin Niessner")); 

    SqlDataAdapter adapter = new SqlDataAdapter(command); 
    DataTable dt = new DataTable(); 

    adapter.Fill(dt); 
} 

En ese ejemplo, el parámetro era @Username y utilizamos la colección Parameters del objeto SqlCommand para pasar en el valor.

+0

¿Alguna buena referencia en consultas parametrizadas para alguien que comienza? –

+0

@Greg es tan fácil como parece. – Will

+0

ok, genial, gracias. –

2

This site tiene una descripción extremadamente completa de lo que está buscando. También hay otherStackOverflowquestions en este tema. Wikipedia también tiene una entrada bastante buena para las inyecciones de SQL.

+0

lindas referencias, gracias, muy útiles –

3

Aquí se muestra un ejemplo:

 SqlConnection myConn = new SqlConnection("my connection string"); 

     SqlCommand myCmd = new SqlCommand("myStoredProcName", myConn); 

     myCmd.CommandType = CommandType.StoredProcedure; 

     myCmd.Parameters.AddWithValue("@cGroupID", 0).Direction = ParameterDirection.InputOutput; 
     myCmd.Parameters.AddWithValue("@gType", "C"); 
     myCmd.Parameters.AddWithValue("@requirement", "Y"); 
     myCmd.Parameters.AddWithValue("@usercode", "XX"); 

     myConn.Open(); 
     myCmd.ExecuteNonQuery(); 

     int covID = (int)myCmd.Parameters["@cGroupID"].Value; 

Uso de parámetros es una buena manera de evitar algunos errores, y ayudar a dejar de vectores de inyección. También permite parámetros OUTPUT, como en el ejemplo anterior donde cGroupID regresa con un valor al que puedo acceder.

2

El problema principal con la simple concatenación de cadenas es que a menudo lo deja vulnerable a los ataques de inyección de SQL.

Google SQL Injection o lea here.

9

Te protegerá de las pequeñas Bobby Tables.

http://xkcd.com/327/

+0

jaja, o wow, ese tiene que ser el comic más geek que he visto ... ¡pero estoy seguro de que puede empeorar! de todos modos, gracias, entiendo lo que dices. –

1

Además de inyección SQL y las consultas con parámetros, como siempre tienen el mismo aspecto que el servidor SQL. Lo más probable es que el plan de ejecución de consultas se almacene en caché, por lo que si envía la misma consulta nuevamente, se ejecutará más rápido. Esto sería muy notable si está ejecutando la misma consulta muchas veces en un bucle o si tiene muchos clientes que consultan su servidor.

Cuestiones relacionadas