Главная » 2009 » Апрель » 5 » Защита сайта от взлома
18:36
Защита сайта от взлома
В данной статье я хотел бы затронуть некоторые аспекты защиты веб-приложений от взлома. Здесь я хочу разобрать некоторые применяемые для взлома сайтов методы и показать, в свою очередь способы предотвращения таких атак.

Для начала давайте определимся, в Интернете только те данные полностью безопасны, которые создали Вы сами! Все остальные данные необходимо проверять и еще раз проверять, а проверив фильтровать!

В приложение злонамеренные данные могут попасть только несколькими способами, основные, и наиболее часто используемые, это загрузка данных в приложение методами GET и POST. То есть любая форма, расположенная на сайте потенциально опасна, будь то сложная форма заполнения персональной информации на сайте пентагона, или простая форма ввода логина и пароля. Обе эти формы несут одинаковую опасность для Вашего приложения. С защиты Вашего сайта от подобных атак и начнем.

Теперь опишу некоторые важные допущения этой статьи необходимые для понимания того, как именно я произвожу защиту своих приложений: допущение первое и единственное, Вы пишите свои сайты на пятой версии PHP. Хотя некоторые из приемов в той или иной степени сработают и на четвертой версии. Первое из того, что Вам необходимо сделать - это отключить в настройках php переменную register_globals (register_globals=off).

Или писать код полностью в объектно орентированном подходе. А лучше сделать и то и другое сразу. Это Вам необходимо для полного контроля над информацией, которую использует Ваше приложение.

Создатели php в пятой версии позаботились о том, что бы нам было удобнее защищать свои приложения. Все данные, приходящие от пользователя сгруппированы в суперглобальные массивы. И как с любыми массивами мы можем с ними сделать довольно многое.

Давайте начнем.

Напишем класс, который обеспечит защиту Вашего приложения от постороннего вторжения. Назовем его скажем, protection

final class protection {
}
?>

Мы объявили этот класс финальным для того, что бы потом по невнимательности не унаследовать его и не перегрузить методы защиты приложения. Хотя это и совсем не обязательно.

Теперь создадим в классе несколько свойств, которые заменят нам те суперглобальные массивы, которые нам предоставили разработчики php. Зачем? Ответ прост - в этих массивах будут лежать проверенные данные. А массивы с данными, которые пришли от пользователя мы очистим.

final class protection {
static public $_get;
static public $_post
}
?>

Эти два свойства класса объявлены статическими для того, что бы иметь к ним доступ из любого места нашего приложения, и при этом гарантировать неизменность находящихся в них данных. Напомню, статические члены класса не нужно создавать вызывая конструктор класса (new) и они доступны в любом месте приложения (некий аналог суперглобальных массивов).

Теперь давайте возьмемся за методы класса. Их тоже будет два по числу наших массивов.

final class protection {
static public $_get;
static public $_post

static public post_decode(){
}
static public get_decode(){
}
}
?>

Методы у нас опять же статические. Специально для того, что бы избежать вызова конструктора класса.

Посмотрим внимательно на информацию, передаваемую методом GET. Выглядит передача информации следующим образом - ?name=name&mode=1.... и так далее. То есть данный массив представляет собой простой набор пар ключ-значение. Значит, мы можем обойти массив, перенося данные в другой массив и при этом проверяя данные...

static public get_decode(){
foreach($_GET as $key=>$value){
$key=htmlspecialchars($key);
if(is_string($value)){
$value=htmlspecialchars($value);
self::$_get[$key]=$value;
}elseif(is_int($value)){
$value=(int)$value;
self::$_get[$key]=$value;
}
}
$_GET=array();
}

В данном случае, для примера, защита данных была осуществлена функцией htmlspecialchars(), которая преобразует все символы способные причинить вред приложению в их символьное представление. В подавляющем большинстве случаев этого вполне достаточно. Но естественно, в случае, когда необходима более надежная защита, используйте регулярное выражение или комбинацию из нескольких защитных функций.

Поверте, безопасность стоит потраченных на проверку данных ресурсов системы. Обратите внимание, в конце функции мы заполнили массив GET пустым массивом. Попросту говоря, стерли его. Сделали мы это для того, что бы если по каким-то причинам (например, забыли, или подключили старый код...) мы случайно обратимся к этому массиву, не отфильтрованные данные все равно не попадут в наше приложение.

Теперь посмотрим на проверку массива данных POST. Этот массив гораздо сложнее. Теоретически, это многомерный массив с неограниченной вложенностью. На практике мне никогда (а пишу я уже 5 лет) не приходилось сталкиваться с необходимостью передавать методом post более чем двух мерные массивы данных. И если такое придется делать Вам, то наверное стоит задуматься над вопросом, как можно упростить приложение.

Итак: Примем допущение, что массив будет самое большее двухмерным. И попробуем реализовать функцию проверки массива.

static public post_decode(){
foreach($_POST as $key=>$value){
$key=htmlspecialchars($key);
if(is_array($value)){
$value=$value;
foreach($value as $sub_key=>$sub_value){
$sub_key=htmlspecialchars($sub_key);
if(is_string($sub_value)){
$sub_value=htmlspecialchars($sub_value);
}elseif(is_int($sub_value)){
$sub_value=(int)$sub_value;
}
self::$_post[$key][$sub_key]=$sub_value;
}
}elseif(is_string($value)){
$value=htmlspecialchars($value);
self::$_post[$key]=$value;
}elseif(is_int($value)){
$value=(int)$value;
self::$_post[$key]=$value;
}
}
$_POST=array();
}

Как видите технически функция ничем не отличается от предыдущей, кроме проверки на то является ли элемент массивом, и соответственно проверке этого массива в этом массиве. В конце функции мы точно так же уничтожаем суперглобальный массив.

Теперь я полностью приведу код класса:

final class protection {
static public $_get;
static public $_post;

static public post_decode(){
foreach($_POST as $key=>$value){
$key=htmlspecialchars($key);
if(is_array($value)){
$value=$value;
foreach($value as $sub_key=>$sub_value){
$sub_key=htmlspecialchars($sub_key);
if(is_string($sub_value)){
$sub_value=htmlspecialchars($sub_value);
}elseif(is_int($sub_value)){
$sub_value=(int)$sub_value;
}
self::$_post[$key][$sub_key]=$sub_value;
}
}elseif(is_string($value)){
$value=htmlspecialchars($value);
self::$_post[$key]=$value;
}elseif(is_int($value)){
$value=(int)$value;
self::$_post[$key]=$value;
}
}
$_POST=array();
}
static public get_decode(){
foreach($_GET as $key=>$value){
$key=htmlspecialchars($key);
if(is_string($value)){
$value=htmlspecialchars($value);
self::$_get[$key]=$value;
}elseif(is_int($value)){
$value=(int)$value;
self::$_get[$key]=$value;
}
}
$_GET=array();
}
}
?>

Это вполне рабочий код, для его использования необходимо подключить файл с классом в начале вашего приложения (например функцией include) и сразу за подключением произвести два вызова наших только что написанных методов:

protection::get_decode();
protection::post_decode();

К супер глобальным массивам мы теперь будем обращаться следующим образом:

protection::$_get;
protection::$_post;

Все! Теперь наше приложение не так легко взломать. Все данные, которые передаются в адресной строке браузера или через формы ввода надежно фильтруются. Как показывает практика, данная защита останавливает примерно 80% Хакеров.

Категория: Живопись | Просмотров: 820 | Добавил: azax | Рейтинг: 0.0/0
Всего комментариев: 0
avatar
close