防止 ASP.Net 中的 SQL 注入

发布于 2024-09-28 23:52:30 字数 2618 浏览 5 评论 0原文

我有这段代码,

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 注入安全的帮助,那么请这样做。

更新号 2

我在代码中添加了 VasilP 所说的

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

但我收到错误工具未声明 我需要指定某个命名空间才能使其工作吗?

更新

有没有人知道如何最好地让我的查询免受 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'. 

这是因为它没有用 69836 替换 @investor

有什么想法吗?

解决方案

这是我解决问题的方法

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 注入

I have this code

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

How would I prevent SQL Injections on this?

UPDATE

Here's what i'm trying

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

For some reason everything I try and add it doesn't seem to work I keep getting SQL Command mentioned below.

The error is this

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

I'm taking over someone else's work so this is all new to me and I would like do things the right way so if anyone can provide any more help on how to make my query above safe from SQL injections then please do.

UPDATE NO 2

I added in the code as VasilP said like this

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

But I get an error Tools is not declared do I need to specify a certain namespace for it to work?

UPDATE

Has anyone got any ideas on the best of getting my query safe from SQL injection without the errors that i'm experiencing?

UPDATE

I now have it so it work without the parameters bit here's my updated source code any idea why it won't add the parameter value?

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

It works like this

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

The error i'm getting is this

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

And it's because it isn't replacing the @investor with the 69836

Any ideas?

SOLUTION

Here is how I solved my problem

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

Now I can write queries without the worry of SQL injection

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

云仙小弟 2024-10-05 23:52:30

尝试使用参数化查询这里是一个链接http://www.aspnet101.com/2007/03 /parameterized-queries-in-asp-net/

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

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

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

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

连接到另一个 SQL Server 的 T-SQL 语法是什么?


<注意

:您最初的问题是询问分布式查询和链接服务器。这个新语句不引用分布式查询。我只能假设您现在直接连接到数据库。这是一个应该有效的示例。
这是使用 SqlCommand.Parameters 的另一个参考站点

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

已编辑:

好的,杰米·泰勒,我会再次尝试回答您的问题。

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

基本上,问题是 OpenQuery 方法采用一个字符串,您无法将变量作为发送到 OpenQuery 的字符串的一部分传递。

您可以像这样格式化您的查询。符号遵循服务器名称.数据库名称.架构名称.表名称。如果您通过 odbc 使用链接服务器,则省略数据库名称和架构名称,如下所示

    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

Try using a parameterized query here is a link http://www.aspnet101.com/2007/03/parameterized-queries-in-asp-net/

Also, do not use OpenQuery... use the this to run the select

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

More articles describing some of your options:

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

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


Edited

Note: Your original question was asking about distributed queries and Linked servers. This new statement does not reference a distributed query. I can only assume you are directly connecting to the database now. Here is an example that should work.
Here is another reference site for using SqlCommand.Parameters

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

Edited:

Ok Jamie taylor I will try to answer your question again.

You are using OpenQuery becuase you are probably using a linked DB

Basically the problem is the OpenQuery Method takes a string you cannot pass a variable as part of the string you sent to OpenQuery.

You can format your query like this instead. The notation follows servername.databasename.schemaname.tablename. If you are using a linked server via odbc then omit databasename and schemaname, as illustrated below

    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
ゃ懵逼小萝莉 2024-10-05 23:52:30

使用参数而不是连接 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 注入问题:

如何:防止 ASP.NET 中的 SQL 注入

Use parameters instead of concatenating your SQL query.

Assuming your database engine being SQL Server, here's a piece of code which I hope will help.

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

To sum it all up, avoid SQL statement concatenation at all cost, and use parameterized quesries!

Here is an interesting link that brings you through SQL injection problem resolution on MSDN:

How To: Protect From SQL Injection in ASP.NET

仅冇旳回忆 2024-10-05 23:52:30

使用 sql 参数,例如:

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

use sqlparameters like:

SqlCommand cmd = new SqlCommand("Select * from Table where id=@id", con);
cmd.Parameters.AddWithValue("@id", 34);
成熟稳重的好男人 2024-10-05 23:52:30
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)
SqlCommand cmd = new SqlCommand("Select * from Table where ref=@ref", con); 
cmd.Parameters.AddWithValue("@ref", 34);

it does not work because it is written in C#, not VB.

Try something like

Dim cmd As New SqlCommand("Select * from Table where ref=@ref", con)
cmd.Parameters.AddWithValue("ref", 34)
極樂鬼 2024-10-05 23:52:30

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

My preferred way is to let Visual Studio handle it all by creating a DAL:
http://www.asp.net/data-access/tutorials/creating-a-data-access-layer-cs

甜`诱少女 2024-10-05 23:52:30

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

Use LINQ. It parametrizes queries automatically.

暖风昔人 2024-10-05 23:52:30

查看 ORM 作为替代方案(如果您正在构建中等程度的东西,这是一个很好的方法 -大小或大)。配置它需要一点时间,但是开发变得非常快。您可以从本机中选择 Linq to SQL实体框架,或者,尝试任何其他适用于 .NET 的 ORM。

Check out ORM as an alternative (very good way to go if you are building something medium-sized or big). It takes a little time to configure it, but then development becomes VERY fast. You choose from the native, Linq to SQL or Entity Framework, OR, try any other ORM which works with .NET.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文