Защита веб-приложений работающих с базой данных (окончание)
Кстати, очень удобная штука дизель генератор! Берешь с собой и имеешь 220 в любом месте без привязки к электросети.
Ещё одно преимущество параметров – возможность указать для них тип данных. Например, если определить числовой параметр (как это сделано в данном случае для определения параметра 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)’,
Оба механизма поддерживают современные 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-сервера;
- нужно подключаться к базе данных под учётной записью с минимально необходимыми привилегиями.