На главную страницу

Советы PHP-программистам

  1. Тщательно продумайте конечную цель создаваемого продукта. Многие технически совершенные WEB-проекты провалились, т.к. отсутствовали заинтересованные в них пользователи.
  2. Разделите содержимое и логику приложения. Принцип такой-же как и при разделении Web-документа на структуру (HTML-код) и оформление (CSS-каскадные таблицы стилей). Точно также необходимо разделить PHP-код и HTML-код. В противном случае при усложнении проекта с кодом будет все сложнее и сложнее управлять. Приемы:
    • Подключаемые файлы. Этот подход эффективен для статических сайтов.
    • Подключение функций для подключения диначмического содержимого к статическим шаблонам страницы.
    • Система шаблонов.
  3. Очень ответственно относитесь к тестированию конечного продукта.
  4. Делайте код простым для восприятия. Осмысленное именование переменных и функций позволяет читать код почти как обычный текст. Структурируйте код – это упрощает восприятие.
  5. Комментируйте тексты программ. Имеет смысл добавлять комментарии к следующим элементам продукта:
  6. Файлам (назначение файла) и Функциям (какие действия функция выполняет, данные вводятся и что возвращается).
  7. Блокам внутри сценария или функции (что будет производиться).
  8. Сложным элементам кода, тогда не придется мучительно вспоминать что делает этот код.
  9. Оптимизируйте и упрощайте код. Вот некоторые проверенные методы:
    • Снижайте количество подключений и ускоряйте запросы к базам данных.
    • Сведите к минимуму генерации статистического содержимого из PHP-кода. Помните фрагмент HTML-кода генерируемый операторами echo и print приводит замедлению работы приложения.
    • Используйте функции обработки строк вместо регулярных выражений.
    • Старайтесь заменить двойные кавычки одинарными. Дело в том, что PHP выискивает переменные пытаясь заменить их значениями. Строки с одинарными кавычками не анализируются. Но лучше избавтесь от строк полностью, заменив их статическим HTML-содержимом.
  10. Фрагментируйте код и разбивайте его на блоки. Это дает следующие преимущества:
    • Упрощает чтение и понимание кода.
    • Улучшает возможность многократного использования кода.
    • Упрощает разработку и отладку.
  11. Распределите каталоги для размещения будущего проекта между компонентами, содержимом и совместно используемыми библиотеками кода.
  12. Создавайте прототипы. Обычно прототип представляет собой частично работающую версию приложения. Зачастую окончательная версия получается в результате многочисленных переделок прототипа.
БЕЗОПАСНОСТЬ PHP-СКРИПТОВ

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

Файлы

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

Доходит до анекдота - "хочу, чтобы было index.php?module=news потому, что news.php - не солидно, сайт не выглядит крутым!".

Для борьбы с такими подстановками есть несколько методов. Можно проверять имя файла регулярками, но мне ближе всего функция basename(), которая отрезает от имени файла все лишнее. Если надо передавать файл вместе с путем к нему, к примеру, themes/green/balloons.php, то проверка будет сложнее. Лучше передавать только имя файла. Или не передавать ничего.

Заливка файлов на сервер Поскольку сервер различает файлы по их расширению, то расширение проверять обязательно.

Функция Eval

Эта функция выполняет строку как PHP код. Функция eval может оказаться полезной во многих случаях. Например, можно сохранить фрагмент кода в базе данных, а затем прочитать его с помощью этой функции. Можно сгенерировать код в цикле, а затем с помощью eval выполнить его.

Пример:

$string = 'Москва';
$name = 'Валера';
$str = 'Я из города $string и меня зовут $name.';
// Печатаем заданную строковую переменную
echo $str. "<br>";
// запаковываем строку в двойные кавычки и выводим результат
eval("\$str = \"$str\";");
echo $str. "<br>";

Результат выполнения приведенного примера:

Я из города $string и меня зовут $name.
Я из города Москва и меня зовут Валера.

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

При этом следует понимать, что пользовательские данные остаются таковыми и после того, как пользователь непосредственно отправил их в скрипт. Полученные из базы данных при последующих исполнениях скрипта, они не становятся менее опасными.

Mail Injection Нельзя допускать наличие переводов строки в данных, которые попадут в заголовки письма.

XSS

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

Методы весьма разнообразны и многочисленны, однако наиболее распространенный и опасный - это внедрение JavaScript инструкций в безобидные теги - <img>, <a> и так далее.

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

Но главная проблема при защите от XSS - не сам метод, а последовательность его применения. практически все известные атаки были произведены в тех частях сайта, где никто и подумать не мог об обработке пользовательских данных. А зря. Обрабатывать их надо везде и всегда.

Так же к этому разделу можно отнести атаки на сессии.

HTTP Injection

XSS уязвимость, похожая на mail injection, только объектом атаки являются не заголовки письма, а HTTP-заголовки. Атака экзотическая, но знать про неё надо. Хакеру ничего не стоит дописать к урлу код с яваскриптом, который благополучно через переменную PHP_SELF или REQUEST_URI программист сам вставит в свою страницу.

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

Со времени появления PHP в нем есть одна, очень неприятная функциональность: получить пользовательские данные в своем скрипте можно совсем того не ожидая. Да-да, речь идет о register_globals. Если эта директива включена, пользователь может создать в скрипте любую переменную с любым содержимым, если только она не была создана программистом. А программисты часто это делать забывают, к примеру, если мы имеем код:

if ($login=="login" AND $password=="password") $admin=1;
и в дальнейшем проверяем переменную $admin, то любой может получить права админа, просто дописав в адресной строке index.php?admin=1.

Лекарством от этого служит принудительная инициализация всех переменных перед использованием.

В строгих языках, таких, как Pascal, невозможно использовать переменную, предварительно не объявив. В PHP это возможно, но злоупотреблять этим не стоит - следует объявлять все переменные перед использованием.

В качестве же временной заплатки можно порекомендовать register_globals=off.

Полезная рекомендация для встраивания переменных в текст:

Если Вы используете при написании PHP-текстов инструментальную систему, в которой автоматически выделяются переменные в контексте, то лучше специально обрамлять положение переменной в тексте:


Можно: echo "Рeзультат: $rezult";
Но лучше: echo "Рeзультат: ".$rezult;
или: echo 'Рeзультат: '.$rezult; - зная о повышенном внимании PHP к двойным кавычкам.

Такой подход также повышает наглядность при формировании запросов к СУБД MySQL:


Запрос:
$res = query("SELECT * FROM user WHERE $id_user = '$id_user' ");
лучше записать как:
$res = query("SELECT * FROM user WHERE $id_user = ' ".$id_user." ' ");

Обращение к функциям через переменные

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

Переменные функции не будут работать с такими языковыми конструкциями как echo(), print(), unset(), isset(), empty(), include(), require() и другими подобными им операторами. Вам необходимо реализовывать свою функцию-обертку (wrapper) для того, чтобы приведенные выше конструкции могли работать с переменными функциями.

Пример. Работа с функциями посредством переменных

function echoit($string)
{
    echo $string;
}

$func = 'echoit';
$func('test');  // Вызовет функцию echoit() и выведен на экран: test

Все что ранее было сказано про переменные также распространяется на работу с функциями через переменные.

Будьте внимательны, осторожны и последовательны!

В начало страницы
Hosted by uCoz