Создание веб сайтов
php технологии, разработка сайтов на php

Проблемы безопасности в PHP происходят из-за некачественного PHP-кода, а
не из-за того, что PHP плох, как язык. Он просто даёт вам широкие возможности, при-
годные и для того, чтобы вы могли навредить себе тоже. ("It just gives you enough rope to
hang yourself.") Есть множество прекрасных пособий (как online, так и книг) которые из-
лагают методику написания безопасного PHP кода. Мы лишь кратко затронем несколько
аспектов безопасности.
Для более глубокого изучения данной темы, пожалуйста скачайте и прочтите
"Открытое руководство по безопасности PHP от Консорциума по безопасности PHP"
("PHP Security Consortium's free PHP Security Guide")
Аутентификационные параметры доступа к СУБД НИКОГДА, повторяю, НИ-
КОГДА не должны быть помещаемы в пределах каталога веб сервера. Хотите знать поче-
му? Сходите сюда: http://www.google.com/search?q=inurl%3Adb.inc (впервые опублико-
ванно в блоге Chris Shiflett). Если Ваши данные доступа помещены в корне вебсервера,
потенциально кто угодно в состоянии как следует повеселиться с вашей базой данных.
Если это произойдет, то любые персональные данные и пароли могут быть украдены.
Лично я предпочитаю хранить всю информацию доступа (БД, файлы паролей, кон-
фигурационные файлы) в каталоге доступа, или произвольном, вне корневого каталога
web. И тогда я просто включаю их в выполняемый скрипт.
Примечание переводчика: На самом деле, приведенный пример дыры имеет место
быть не потому, что файл с логином и паролем лежит внутри каталога веб-сервера, а
потому, что он имеет не ассоциированное с PHP расширение ".inc", в результате чего
Apache (или другой веб-сервер) просто отдает его содержимое по запросу веб-браузера,
как обычный, неисполняемый файл. Выход в том, чтобы отказаться от хранения скрип-
тов и их данных в любых файлах, отличных от расширения .php, или отделять их в ка-
талоги, для которых веб-серверу запрещен доступ, например, для Apache директивами
<Directory /var/www/mysite/mydata>
Deny from All
</Directory>
В том случае, когда вы храните пароли в виде части PHP кода, в файле, например,
db.inc.php - пользователь (тот же Google) не сможет получить его содержимое, он по-
лучит лишь результат его выполнения. В свою очередь, напротив, доступ интерпрета-
тора PHP к файлам вне каталога вебсервера лучше ограничить директивами файла
<Directory>
/var/www/mysite/>php_admin_value open_basedir /var/www/mysite/
</Directory>
дабы если уж злоумышленник и взломает ваш скрипт, он не смог получить до-
ступа к остальным файлам системы.

Проверяйте вводимые данные

НИКОГДА, НИКОГДА, НИКОГДА не доверяйте данным, введенным пользова-
телем. Мне нужно повторить? Никогда не доверяйте данным, введенным пользователем.
Не буду перечислять все причины почему нет, но скажу, что принятые "плохие" данные
от пользователя могут доставить огромные неприятности вашему скрипту.
31
PHP Inside #17 Идеи
Лучшая практика
Так что же нам делать, если мы не доверяем вводимым данным? Проверять всё, что
нам подают на вход. PHP располагает рядом функций, способном вам в этом помочь. К
сожалению, у меня нет времени и достаточного места, чтобы рассмотреть их все, так что
я только укажу несколько опций в примере. Обязательно рассмотрите функции из приме-
ра и все с ними связанные.
<?php
if ((isset($_POST["username"]) &&
(trim($_POST["username"]) != "") && (ctype_alnum(trim($_POST["username"]))) &&
(strlen(trim($_POST["username"])) >= 4) && (strlen(trim($_POST["username"])) <=
10))
?>
Ммм.. Всё еще не упомянуты функции регулярных выражений, функция checkdate
() и возможно еще несколько, но я думаю вы уловили общую мысль.

Необходимо обезопасить вывод

Зачем обрабатывать вывод, когда вы так старательно обрабатываете ввод? Ну, не-
важно насколько мы умны (или думаем, что умны), кто-то всегда умнее. Так что, мы
должны убедиться, что ничего вредоносного, даже если оно "проберется" сквозь нашу
фильтрацию ввода, не сможет ничего натворить при выводе страницы (что-то, навроде
"дефейса" вашей страницы или вредоносного же JavaScript). Итак, как обезопасить вы-
вод? Ну, addslashes(), urlencode() и htmlentities() - хорошее начало.
<?php
$query = sprintf("INSERT INTO myTable (comments) VALUES('%s')",
mysql_real_escape_string($comments));
echo "Следущий комментарий будет добавлен в базу данных:<br />";
echo htmlentities($content);
?>

Инициализация переменных

Просто производите инициализацию. Если вы не сделаете этого, кто-то другой сде-
лает это, что приведет к печальным последствиям и огромным дырам в безопасности.
Это включает переменные, которые могут придти в ваш скрипт извне, скажем POST или
GET переменные, к примеру. Если вы используете в вашем скрипте временную перемен-
ную - убедитесь в том, что вы присваиваете ей начальное значение. Используйте тринар-
ный оператор для POST, GET и REQUEST перменных:
<?php
$user = (isset($_POST['user']))?$_POST['user']:'';
?>