Защита веб-приложений работающих с базой данных (окончание)

Ещё одно преимущество параметров – возможность указать для них тип данных. Например, если определить числовой параметр (как это сделано в данном случае для определения параметра age), то строгий контроль типов пресечёт на корню множество SQL -атак, поскольку они не возможны с использованием только чисел. Если приложение поддерживает интерфейс ODBC и требуются параметры, применяйте функцию SQLNumParametrs и SQLBindParametrs. При работе с OLE DB задействуйте интерфейс IComandWithParametrs. А если, как в данном случае, используется управляемый код, то используйте класс SqlCommand.

Что касается безопасных хранимых процедур, тот тут разговор пойдёт несколько по-другому.

Только что продемонстрированные параметризованные запросы пригодны для доступа к БД из внешних приложений, таких как Web-сервисы. Однако, когда требуется выполнять те же действия в хранимых процедурах, следует знать о двух простых механизмах, помогающих создавать безопасные выражения.

Во-первых, следует применять к именам объектов функцию quotename. Например, выражение select top 3 name from mylabk- превратится в select top 3 [name] from [mytable], если вы выделите квадратными скобками name и mytable.

Quotename – это очень полезная встроенная функция transactSQL. Она выделяет имена объектов разделителями, анализируя неправильные символы.

Результат ее работы можно увидеть, запустив в SQL Query Analyzer приведённый пример:

declare @a varchar (20) set @a=0x74735D27 select @a

set @a=quotename(@a) select @a

set @a=’ts]”’ select @a

set @a=quotename(@a) select @a

Обратите внимание на значение переменноё @a во втором блоке кода. Она превратилась в безопасную строку, выделенную символами «[» и «]».

Во-вторых, следует использовать sp_executesql для исполнения динамически созданных SQL-выражений, вместо того чтобы просто склеивать строки.

declare @name varchar(64) set @name=N’White’ exec sp_executesql

N ‘select * from clients where [email protected]’,

N ‘@lname varchar(64)’,

@[email protected]

Оба механизма поддерживают современные SQL-сервера, и разработчики, создающие хранимые процедуры, должны учитывать эти особенности!

Также при написании приложений, в которых формируются SQL-запросы нужно контролировать корректность введённых данных с помощью регулярных выражений. Например, для контроля правильности идентификационного кода можно использовать такое регулярное выражение: A\d{2,10}$.

Базу данных стоит хранить на отдельном сервере, а не на том, где установлен Web-сервер.

И, что немаловажно, никогда не стоит выводить ошибки пользователю (а возможно, хакеру)

Да, но как же тогда отлаживать такие приложения?

Для этого рекомендуется отлов ошибок строить следующим образом:

try {

//код, в котором нужно перехватывать ошибки } catch (Exception e) {

//проверяем, если пользователь зашел с локального компьютера

//то выводим полное сообщение об ошибке

if (httpContext.Curent.Request.UserHost.Address = = “127.0.0.1”)

Status=e.ToString(); else

Status = “При обработке запроса произошла ошибка!”; } finaly { if (cmd != null )

cmd.Connection.Close();

}

В данном коде ошибка выводится только в том случае, если приложение просматривается с комп’ютера, адрес которого 127.0.0.1. А это, как известно, статический локальный адрес.

Существует ещё одна возможность вывода сообщения «избранным» пользователям, т. е. только тем, которые не намерены причинить вред данному Web-узлу, а именно администраторам:

AppDomain.CurentDomain.SetPrincipialPolicy (PrincipalPolicy.WindowsPrincial)

WindowsPrincipal user = (WindowsPrincipal)Therd.CurrentPrincipal; if (user.IsInRole(WindowsBuildInRole.Administrator)) {

//пользователь является администратором, поэтому выводим ему подробности об ошибке

Status=e.ToString();

}

И сразу же ещё одно замечание: необходимо всегда закрывать установленное подключение к БД, даже если произошел сбой. Это предотвратит угрозу отказа в обслуживании, обычная причина которых – слишком много открытых подключений.

Приложения, взаимодействующие с базой данных, – одни из самых распространённых видов прикладных программ, и, к сожалению, многие из них уязвимы для атак с внедрением SQL-кода. Следуя простым правилам, можно избавить свои приложения от подобных вещей:

  • никогда не стоит доверять данным, которые ввёл пользователь!
  • проявляйте жесткость и чётко определяйте, что такое «правильные входные данные». Всё, что не соответствует стандарту, безжалостно нужно отвергать! В этом случае лучший помощник – регулярные выражения;
  • для построения запросов нужно применять параметризацию а не конкатенацию строк;
  • не стоит «откровенничать» с хакером, предоставляя ему слишком много информации;
  • нужно хранить базу данных отдельно от Web-сервера;
  • нужно подключаться к базе данных под учётной записью с минимально необходимыми привилегиями.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

%d такие блоггеры, как: