2010-10-25 23 views
9

tengo este códigoPrevención de inyección SQL en ASP.Net

UPDATE OPENQUERY (db,'SELECT * FROM table WHERE ref = ''"+ Ref +"'' AND bookno = ''"+ Session("number") +"'' ') 

¿Cómo puedo prevenir las inyecciones SQL en esto?

ACTUALIZACIÓN

Esto es lo que estoy tratando

SqlCommand cmd = new SqlCommand("Select * from Table where [email protected]", con); 
cmd.Parameters.AddWithValue("@ref", 34); 

Por alguna razón, todo trato y añadir que no parece funcionar sigo recibiendo SQL Command mencionan a continuación.

El error es este

'SqlCommand' is a type and cannot be used as an expression 

Me haré cargo de otra persona de trabajo de modo que todo esto es nuevo para mí y me gustaría hacer las cosas de la manera correcta así que si alguien puede proporcionar más ayuda sobre cómo hacer que mi consulta sea segura a partir de las inyecciones de SQL, por favor hazlo.

ACTUALIZACIÓN NO2

he añadido en el código como dijo VasilP como esto

Dim dbQuery As [String] = "SELECT * FROM table WHERE ref = '" & Tools.SQLSafeString(Ref) & "' AND bookno = '" & Tools.SQLSafeString(Session("number")) & "'" 

pero me da un error Tools is not declared necesito para especificar un cierto espacio de nombres para que funcione?

ACTUALIZACIÓN

Alguien tiene alguna idea de lo mejor de conseguir mi consulta a salvo de inyección de SQL sin los errores que estoy experimentando?

ACTUALIZACIÓN

ahora tengo que trabajar por lo que sin los parámetros de bits del código fuente actualizado mi idea de por qué no va a añadir el valor del parámetro aquí?

Dim conn As SqlConnection = New SqlConnection("server='server1'; user id='w'; password='w'; database='w'; pooling='false'") 
    conn.Open() 


Dim query As New SqlCommand("Select * from openquery (db, 'Select * from table where investor = @investor ') ", conn) 
query.Parameters.AddWithValue("@investor", 69836) 

dgBookings.DataSource = query.ExecuteReader 
dgBookings.DataBind() 

funciona de la siguiente

Dim conn As SqlConnection = New SqlConnection("server='server1'; user id='w'; password='w'; database='w'; pooling='false'") 
    conn.Open() 


Dim query As New SqlCommand("Select * from openquery (db, 'Select * from table where investor = 69836') ", conn) 

dgBookings.DataSource = query.ExecuteReader 
dgBookings.DataBind() 

El error que estoy recibiendo es este

An error occurred while preparing a query for execution against OLE DB provider 'MSDASQL'. 

Y es porque no es la sustitución del @investor con el 69836

¿Algunas ideas?

SOLUCIÓN

Aquí es cómo resolví mi problema

Dim conn As SqlConnection = New SqlConnection("server='h'; user id='w'; password='w'; database='w'; pooling='false'") 

conn.Open() 

Dim query As New SqlCommand("DECLARE @investor varchar(10), @sql varchar(1000) Select @investor = 69836 select @sql = 'SELECT * FROM OPENQUERY(db,''SELECT * FROM table WHERE investor = ''''' + @investor + ''''''')' EXEC(@sql)", conn) 

dgBookings.DataSource = query.ExecuteReader 
dgBookings.DataBind() 

Ahora puedo escribir consultas sin la preocupación de inyección SQL

Respuesta

19

Trate de usar un parameterized query Aquí hay un enlace http://www.aspnet101.com/2007/03/parameterized-queries-in-asp-net/

Además, no use OpenQuery ... use esto para ejecutar los selectos

SELECT * FROM db...table WHERE ref = @ref AND bookno = @bookno 

Más artículos que describen algunas de sus opciones:

http://support.microsoft.com/kb/314520

What is the T-SQL syntax to connect to another SQL Server?


Editado

Nota: Su pregunta original era preguntar acerca de consultas distribuidas y servidores vinculados. Esta nueva instrucción no hace referencia a una consulta distribuida. Solo puedo suponer que ahora se está conectando directamente a la base de datos. Aquí hay un ejemplo que debería funcionar. Aquí hay otro sitio de referencia para el uso de SqlCommand.Parameters

SqlCommand cmd = new SqlCommand("Select * from Table where [email protected]", con); 
cmd.Parameters.Add("@ref", SqlDbType.Int); 
cmd.Parameters["@ref"] = 34; 

Editado:

Ok Jamie Taylor voy a tratar de responder a su pregunta de nuevo.

está usando el AbrirConsulta becuase probablemente se está utilizando una base de datos vinculada

Básicamente el problema es el método AbrirConsulta toma una cadena que no se puede pasar una variable como parte de la cadena que envió a AbrirConsulta.

Puede formatear su consulta así en su lugar. La notación sigue servername.databasename.schemaname.tablename. Si está utilizando un servidor vinculado a través de ODBC y luego omitir nombrebasedatos y SchemaName, como se ilustra a continuación

Dim conn As SqlConnection = New SqlConnection("your SQL Connection String") 
    Dim cmd As SqlCommand = conn.CreateCommand() 
    cmd.CommandText = "Select * db...table where investor = @investor" 
    Dim parameter As SqlParameter = cmd.CreateParameter() 
    parameter.DbType = SqlDbType.Int 
    parameter.ParameterName = "@investor" 
    parameter.Direction = ParameterDirection.Input 
    parameter.Value = 34 
+0

Parece que estoy recibiendo errores al intentar poner algo de esto en mi página –

+0

@Jamie Taylor ... va a necesitar un poco más de detalles que "Parece que estoy recibiendo errores ..." para ayudar vete. –

+0

Sigue obteniendo ''SqlCommand' es un tipo y no se puede utilizar como una expresión' –

5

Utilizar los parámetros en lugar de la concatenación de la consulta SQL.

Suponiendo que su motor de base de datos sea SQL Server, aquí hay un fragmento de código que espero que ayude.

Using connection As SqlConnection = new SqlConnection("connectionString") 
    connection.Open() 

    Using command As SqlCommand = connection.CreateCommand() 
     string sqlStatement = "select * from table where ref = @ref and bookno = @bookno"; 
     command.CommandText = sqlStatement 
     command.CommandType = CommandType.Text 

     Dim refParam As SqlDataParameter = command.CreateParameter() 
     refParam.Direction = ParameterDirection.Input 
     refParam.Name = "@ref" 
     refParam.Value = Ref 

     Dim booknoParam As SqlDataParameter = command.CreateParameter() 
     booknoParam.Direction = ParameterDirection.Input 
     booknoParam.Name = "@bookno" 
     booknoParam.Value = Session("number") 

     Try 
      Dim reader As SqlDataReader = command.ExecuteQuery() 
      ' Do your reading job here...' 
     Finally 
      command.Dispose() 
      connection.Dispose() 
     End Try 
    End Using 
End Using 

Para resumir todo, evite la concatenación de sentencias SQL a toda costa y utilice preguntas parametrizadas.

Aquí es un enlace interesante que te lleva a través de la resolución de problemas de inyección SQL en MSDN:

How To: Protect From SQL Injection in ASP.NET

4

uso SqlParameters como:

SqlCommand cmd = new SqlCommand("Select * from Table where [email protected]", con); 
cmd.Parameters.AddWithValue("@id", 34); 
+2

+1 Para el método 'AddWithValue()'. –

+0

Intenté este método, pero me dio un error ''SqlCommand 'es un tipo y no se puede usar como una expresión' –

1

uso de LINQ. Configura las consultas automáticamente.

2
SqlCommand cmd = new SqlCommand("Select * from Table where [email protected]", con); 
cmd.Parameters.AddWithValue("@ref", 34); 

no funciona porque está escrito en C#, no en VB.

intentar algo así como

Dim cmd As New SqlCommand("Select * from Table where [email protected]", con) 
cmd.Parameters.AddWithValue("ref", 34) 
+0

Gracias, agregué esto pero me aparece un error diferente ahora' No se pudo encontrar el servidor' System 'en sysservers . Ejecute sp_addlinkedserver para agregar el servidor a sysservers' ¿Alguna idea de lo que significa? –

+1

Debería verificar su cadena de conexión, ahora es un error de base de datos, no ASP.NET. –

1

Salida ORM como alternativa (muy buena manera de ir si usted está construyendo algo de tamaño mediano o grande). Lleva un poco de tiempo configurarlo, pero luego el desarrollo se vuelve MUY rápido. Puede elegir entre el nativo, Linq to SQL o Entity Framework, O bien, pruebe any other ORM, que funciona con .NET.

Cuestiones relacionadas