Предотвращение SQL-инъекций в ASP.Net - PullRequest
9 голосов
/ 25 октября 2010

У меня есть этот код

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

Как бы я предотвратить SQL-инъекции на этом?

UPDATE

Вот что я пытаюсь

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")) & "'"

Но я получаю сообщение об ошибке Tools is not declared мне нужно указать определенное пространство имен, чтобы оно работало?

UPDATE

У кого-нибудь есть идеи, как лучше защитить мой запрос от внедрения SQL без ошибок, с которыми я сталкиваюсь?

UPDATE

Теперь он у меня есть, поэтому он работает без параметров. Вот мой обновленный исходный код. Есть идеи, почему он не добавляет значение параметра?

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 ]

19 голосов
/ 25 октября 2010

Попробуйте использовать параметризованный запрос вот ссылка 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

Что такое синтаксис T-SQL для подключения к другому 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;

Отредактировано:

Хорошо, Джейми Тейлор Я постараюсь ответитьВаш вопрос снова.

Вы используете OpenQuery, потому что вы, вероятно, используете связанную БД

В основном проблема заключается в том, что метод OpenQuery принимает строку, которую нельзя передать переменной, как часть строки, которую вы отправилив OpenQuery.

Вы можете вместо этого отформатировать ваш запрос.Обозначение следует за servername.databasename.schemaname.tablename.Если вы используете связанный сервер через 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
5 голосов
/ 25 октября 2010

Используйте параметры вместо конкатенации вашего 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 любой ценой и используйте параметризованные запросы!

Вот интересная ссылка, которая поможет вам решить проблему с инъекцией SQL в MSDN:

How To: Protect From SQL Injection in ASP.NET

4 голосов
/ 26 октября 2010

используйте sqlparameters, как:

SqlCommand cmd = new SqlCommand("Select * from Table where id=@id", con);
cmd.Parameters.AddWithValue("@id", 34);
2 голосов
/ 28 октября 2010
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)
2 голосов
/ 25 октября 2010

вы можете использовать параметризованные запросы.

http://www.functionx.com/aspnet/sqlserver/parameterized.htm

1 голос
/ 04 ноября 2010

Проверьте ORM в качестве альтернативы (очень хороший способ, если вы строите что-то среднего или большого размера). На его настройку уходит немного времени, но затем разработка становится ОЧЕНЬ быстрой. Вы выбираете из нативного Linq to SQL или Entity Framework ИЛИ, попробуйте любой другой ORM, который работает с .NET.

1 голос
/ 26 октября 2010

Используйте LINQ.Он параметризует запросы автоматически.

1 голос
/ 25 октября 2010

Мой предпочтительный способ - позволить Visual Studio все это обработать, создав DAL: http://www.asp.net/data-access/tutorials/creating-a-data-access-layer-cs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...