在ASP.Net中防止SQL注入

时间:2010-10-25 19:36:21

标签: asp.net sql sql-server vb.net sql-injection

我有这段代码

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

我如何阻止SQL注入?

更新

这是我正在尝试的

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

出于某种原因,我尝试添加它的所有内容似乎都无法正常工作我会继续提到下面提到的SQL Command

错误就是这个

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

我正在接管其他人的工作,所以这对我来说是全新的,我想以正确的方式做事,所以如果有人能提供更多帮助,如何使我的查询在SQL注射之上安全,那么请做。

更新NO 2

我在代码中添加了像VasilP这样说的

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

但我收到错误Tools is not declared我是否需要指定某个命名空间才能使其正常工作?

更新

有没有人在没有我遇到的错误的情况下有任何关于从SQL注入中获得安全保护的想法?

更新

我现在已经拥有它所以它的工作没有参数位这里我更新的源代码知道为什么它不会添加参数值?

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()

它像这样工作

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()

我得到的错误就是这个

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

这是因为它没有用@investor

替换69836

有什么想法吗?

以下是我解决问题的方法

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()

现在我可以编写查询而无需担心SQL注入

8 个答案:

答案 0 :(得分:19)

尝试使用parameterized query,这是一个链接http://www.aspnet101.com/2007/03/parameterized-queries-in-asp-net/

另外,不要使用OpenQuery ...使用它来运行select

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

更多描述您的选择的文章:

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

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


<强>被修改

注意:您的原始问题是询问分布式查询和链接服务器。此新语句不引用分布式查询。我现在只能假设您正在直接连接到数据库。这是一个应该有效的例子。 以下是使用SqlCommand.Parameters

的另一个参考网站
SqlCommand cmd = new SqlCommand("Select * from Table where ref=@ref", con); 
cmd.Parameters.Add("@ref", SqlDbType.Int);
cmd.Parameters["@ref"] = 34;

<强>编辑:

Ok Jamie taylor我会再次尝试回答你的问题。

您正在使用OpenQuery,因为您可能正在使用链接数据库

基本上问题是OpenQuery方法接受一个字符串,你不能将变量作为发送给OpenQuery的字符串的一部分传递。

您可以像这样格式化查询。表示法遵循servername.databasename.schemaname.tablename。如果您通过odbc使用链接服务器,则省略databasename和schemaname,如下所示

    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

答案 1 :(得分:5)

使用参数而不是连接SQL查询。

假设您的数据库引擎是SQL Server,这里有一段代码,我希望能提供帮助。

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

总结一下,不惜一切代价避免SQL语句连接,并使用参数化问题!

这是一个有趣的链接,它带您了解MSDN上的SQL注入问题解决方法:

How To: Protect From SQL Injection in ASP.NET

答案 2 :(得分:4)

使用sqlparameters,如:

SqlCommand cmd = new SqlCommand("Select * from Table where id=@id", con);
cmd.Parameters.AddWithValue("@id", 34);

答案 3 :(得分:2)

答案 4 :(得分:2)

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

它不起作用,因为它是用C#编写的,而不是VB。

尝试类似

的内容
Dim cmd As New SqlCommand("Select * from Table where ref=@ref", con)
cmd.Parameters.AddWithValue("ref", 34)

答案 5 :(得分:1)

我首选的方法是让Visual Studio通过创建DAL来处理所有这些: http://www.asp.net/data-access/tutorials/creating-a-data-access-layer-cs

答案 6 :(得分:1)

使用LINQ。它会自动参数化查询。

答案 7 :(得分:1)

查看ORM作为替代方案(如果您正在构建中型或大型的东西,那么非常好的方法)。配置它需要一点时间,但随后开发变得非常快。您可以选择本机,Linq to SQLEntity Framework,或者尝试使用与.NET一起使用的any other ORM。