8 способов защитить ваше веб приложение

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

  1. Валидация входящих данных
  2. Защита от XSS атак
  3. Защита от CSRF атак
  4. Предотвращение SQL инъекций
  5. Защита файловой системы
  6. Защита данных сессии
  7. Обработка ошибок
  8. Защита подключаемых файлов

Валидация входящих данных

Во время проектирования приложения, вам нужно стремиться защитить его от “плохих” входящих данных. Правило, которому нужно следовать, звучит примерно так: “Никогда не верьте тому, что ввёл пользователь”. Несмотря на то что большинство пользователей не представляют угрозы, всегда есть вероятность того, что кто-то захочет хакнуть ваш сайт, используя “плохие” данные, вводимые через формы или адресную строку. Если вы всегда проверяете и фильтруете входящие данные, то у вас неплохие шансы написать безопасное приложение.

Всегда проверяйте ваши данные в PHP скриптах. Если же вы используете JavaScript для валидации данных, то в любой момент злоумышленник может отключить его в своём браузере. В таком случае ваше приложение в опасности. Никто не против JavaScript валидации, но для хорошей защиты вам необходимо перепроверять данные в PHP скриптах.

Защита от XSS атак

Межсайтовый скриптинг или XSS атака - это атака, основанная на внедрении кода на потенциально уязвимых страницах. Опасность в том, что вредоносный код может быть введён через формы, а затем отображён в браузере.

Предположим, на вашем сайте есть форма для ввода комментариев, которые сразу же отображаются после добавления. Злоумышленник может ввести комментарий, содержащий JavaScript код. После отправки формы, данные переправляются на сервер и заносятся в базу данных. После этого данные извлекаются из базы и новый комментарий отображается на HTML странице, включая и внедрённый JavaScript код. Он может перенаправлять пользователя на какую-то вредоносную страницу или на фишинговый сайт.

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

Защита от CSRF атак

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

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

Следующий простой пример показывает как незащищённый сайт может подвергнуться CSRF атаке:

<?php
if (isset($_REQUEST["name"], $_REQUEST["amount"])) {
  // обработка запроса и перевод количества (денег) от авторизованного пользователя
  // пользователю с именем переданным через GET запрос
}

Предположим, что Боб хочет совершить CSRF атаку над Алисой. Он сформировал специальный url адрес и отправил его Алисе на e-mail:

<a href="http://example.com/process.php?name=Bob&amount=1000">Посети мой сайт!</a>

Если Алиса авторизована на сайте example.com и пройдёт по данной ссылке, то с её счёта на счёт Боба будет переведено $1000. В качестве альтернативы Боб может отправить и изображение, а в атрибуте src внести “плохой” адрес.

<img src="http://example.com/process.php?name=Bob&amount=1000" width="1" height="1"/>

Браузер не сможет отобразить данное изображение, так как его не существует, однако запрос будет совершён без ведома и участия Алисы.

В качестве предотвращения подобного рода атак, используйте только POST запросы к процессам, предназначенным для изменения информации в базе данных. Не используйте $_REQUEST. Пользуйтесь $_GET-ом для обработки GET параметров, и $_POST для извлечения POST параметров.

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

Предотвращение SQL инъекций

Для выполнения запросов к базе данных следует использовать PDO. Благодаря параметризированным запросам и подготовленным выражениям, вы можете свести на нет угрозу SQL инъекций.

Давайте рассмотрим следующий пример:

<?php
$sql = "SELECT * FROM users WHERE name=:name and age=:age";
$stmt = $db->prepare($sql);
$stmt->execute(array(":name" => $name, ":age" => $age));

В коде, представленном выше, мы отправляем запрос в метод prepare(), включая именные параметры: :name и :age. Таким образом, запрос пре-компилируется для дальнейшей подстановки данных. При вызове метода execute(), запрос полностью формируется и выполняется. Если вы пользуетесь подобной техникой, то все попытки злоумышленника осуществить SQL инъекцию будут сведены к нулю.

Защита файловой системы

Как ответственный разработчик, вы должны всегда писать такой код, который не подставит под риск вашу файловую систему. Давайте рассмотрим код, которой отдаёт на скачку файл в зависимости от данных, переданных пользователем.

<?php
if (isset($_GET['filename']) {
    $filename = $_GET['filename'];
    header('Content-Type: application/x-octet-stream');
    header('Content-Transfer-Encoding: binary');
    header('Content-Disposition: attachment; filename="' . $filename . '";');
    echo file_get_contents($filename);
}

Данный скрипт очень опасен, так как из-за него можно получить доступ к любому каталогу, который доступен из файла со скриптом: к каталогу с сессиями, системным папкам и многому другому.

Защита данных сессии

По умолчанию вся информация сессий записывается в каталог temp. Если вы пользуетесь виртуальным хостингом, кто-то помимо вас может написать скрипт и считать данные сессий. Поэтому остерегайтесь хранения паролей или номеров кредиток в сессиях.

Если же всё-таки вам необходимо хранить подобные данные в сессии, то лучшей мерой будет шифрование. Это до конца не решает проблему, так как зашифрованные данные не на 100% безопасны, однако хранимая информация будет нечитабельной. Также вам стоит подумать о том, что данные сессии можно хранить в другом месте, таком, как база данных. В PHP есть специальный метод session_set_save_handler(), который позволит вам хранить данные сессий по-своему.

Начиная с PHP 5.4 вы можете передать объект типа SessionHandlerInterface в session_set_save_handler().

Обработка ошибок

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

На публичном сервере вам необходимо отключить такие опции, как display_errors и display_start_up_errors, а вот такие опции как error_reporting и log_errors, должны быть активны, чтоб все ошибки, возникшие у пользователей, записывались в логи.

Также вы можете использовать “set_error_handler” для определения своего собственного обработчика ошибок. Однако тут могут возникнуть ограничения, ведь собственный обработчик уступает родному PHP механизму. Ошибки E_CORE_ERROR, E_STRICT или E_COMPILER_ERROR не смогут быть отловлены в том же файле, где и определённый обработчик. Более того, ошибки, которые могут возникнуть в самом обработчике также не смогут быть отловлены.

Для более элегантного способа отлавливания исключений, потенциально опасный код нужно помещать в блок try/catch. Все собственные исключения должны быть объектами классов или подклассов Exception. Если исключения и были выброшены, то в блоке try/catch их можно обработать.

Защита подключаемых файлов

Часто в PHP скриптах происходит подгрузка других файлов, таких как подключение к базе и многих других. Некоторые разработчики дают таким файлам расширение .inc. Такие файлы по умолчанию PHP не парсит. Если обратиться к ним по адресу напрямую, пользователь сможет увидеть текст данного файла. Если же хакеру удастся получить доступ к файлу хранящиму данные подключение к базе, то в последствии он может получить доступ ко всем данным вашего приложения. Так что всегда используйте расширение .php для подгружаемых файлов и храните их там, куда нет прямого пользовательского доступа.

Итог

Если вы будете следовать перечисленным 8 правилам, то это в значительной мере позволит усилить устойчивость вашего приложения к различного рода атакам. Не доверяйте данным, введённым пользователями, защищайте ваши файлы и базу данных.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://phpmaster.com/8-practices-to-secure-your-web-app/
Перевел: Станислав Протасевич
Урок создан: 1 Марта 2013
Просмотров: 42571
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

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

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 1 Марта 2013 17:55
    biohazardo
    Этих правил должен придерживаться каждый. А еще есть рекомендация осуществлять доступ только через один php-файл с помощью mod_rewrite, типа index.php, а все остальные файлы класть папкой выше, которую не раздает веб-сервер напрямую. Много проблем отметает сразу.
    • 2 Марта 2013 15:01
      Barahten
      а подробнее можно? а то я новенький...
      • 3 Марта 2013 01:19
        rekon
        PHP framework (для новичков советую CodeIgniter)
        • 4 Марта 2013 12:11
          tigerel
          CodeIgniter полон багами.... Лучше Yii изучать, он сложнее но гараздо лудше.
        • 5 Марта 2013 07:34
          Дзирт_До_Урден
          согласен --- CodeIgniter отличная штука. Пользуюсь уже второй год.
  • 2 Марта 2013 15:00
    rubyx
    использую "фреймовый" index.*** пока таких проблем не было :)
  • 2 Марта 2013 16:20
    Ygreec
    Скажите, а при проверке в инструментах вебмастера (в гугле и яндексе), при проверке на вредоносный код - выявляет ли "плохие скрипты", или они не могут такое увидеть?
    • 2 Марта 2013 18:19
      avarietsss
      В гугле или яндекс браузерах вряд ли такое возможно, однако подобные системы или сервисы должны существовать. Стоит поискать, но они наверняка платные.
  • 3 Марта 2013 19:16
    micha
    Понял одно, всё очень опасно. А что конкретно предпринять - не догнал.
    • 4 Марта 2013 16:49
      userseal
      Проверять получаемые из строки данные. Что не понятно? Должно придти число для получения данных из базы intval() и это как миниум, если 0 ошибка или выход. Должна придти строка - всё равно знаете из чего она будет состоять. Проверить регэкспом не сложно, не совпало выход или ошибка. И т.д. И периодически просматривать логи доступа и ошибок на предмет "странных" адресов и запросов к сайту. Просто блокировать эти адреса или перенаправлять в миркософт, к примеру...
  • 4 Марта 2013 17:02
    hercules
    На публичном сервере вам необходимо отключить такие опции, как display_errors и display_start_up_errors, а вот такие опции как error_reporting и log_errors, должны быть активны, чтоб все ошибки, возникшие у пользователей, записывались в логи. У Вас тут опечатка, нет такой функции
    display_start_up_errors
    , есть
    display_startup_errors
  • 14 Марта 2013 22:42
    advetech
    Большое спасибо за статью!
  • 26 Июня 2013 08:15
    Михаил_Гуреев
    Возникли вопросы. 1: Можно ли изменить папку хранения сессий. 2: Написано: "остерегайтесь хранения паролей или номеров кредиток в сессиях", как же тогда выполнять авторизацию пользователей. 3: И можно ли хранить в сессиях хешированный пароль. Спасибо, статья хорошая.
^ Наверх ^