На главную Назад
Добро пожаловать, уважаемый посетитель!

 

 

ГЛАВА 16

Безопасность

Non sumqualis eram

(Я нетакой, каким был раньше).

Гораций

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

Конечно,читатель недоумевает - какое отношениедревнеримский поэт Гораций имеет к сетевойбезопасности? Безопасность - одна из тем,порождающих нескончаемый поток информациии вечно меняющихся в соответствии с новымитехнологическими веяниями. Короче говоря,она в любой момент <не такая, какой былараньше>. Вы никогда не можете полагаться насвои познания в этой области, поскольку вмомент выхода на широкий рынок любаятехнология либо устаревает, либо обреченана устаревание в ближайшем будущем. Чтобыдобиться относительной безопасностипри построении серверных приложений, вампридется постоянно следить за последнимидостижениями в этой области или нанять кого-нибудь,кто это будет делать за вас.

Применительнок РНР тема безопасности выглядитмногогранной, причем некоторые ее аспектысвязаны с безопасностью самого сервера.Ведь безопасность сервера во многихотношениях определяет безопасность данных,обрабатываемых сценариям РНР. Янастоятельно рекомендую собрать как можнобольше информации о вашем web-сервере ипостоянно следить за всеми обновлениями иисправлениями. Вероятно, большинствочитателей работает с сервером Apache, поэтомуя советую почаще посещать сайт Apache (http://www.apache.org)и замечательный сайт Apache Week (http://www.apacheweek.org).Впрочем, безопасностью сервера дело неограничивается - РНР также в определеннойстепени влияет на безопасность системы засчет правильного выбора параметровконфигурации и защищенногопрограммирования.

Последняяглава этой книги состоит из пяти разделов:

  • Проблемыконфигурации.
  • Проблемыпрограммирования.
  • Шифрованиеданных.
  • Электроннаякоммерция.
  • Аутентификацияпользователей.

Хотя ниодин из этих разделов не содержит ответовна все вопросы,относящиеся к построению защищенныхприложений на базе РНР, по крайней мере, онизакладывают основу для дальнейшихсамостоятельных исследований.

Проблемыконфигурации

Сразу жепосле установки РНР следует уделитьвнимание некоторым аспектам конфигурации,влияющим на безопасность вашей системы.Конечно, выбор зависит от конкретнойситуации. Например, если программированиемна РНР будете заниматься только вы и вашиколлеги, то конфигурация системыбезопасности будет выглядеть совсем не так,как если бы программирование сценариев РНР,работающих на сервере, разрешалось всемклиентам. Независимо от ситуации, следуетвнимательно проанализировать всепараметры конфигурации и разрешить толькото, что действительно необходимо. Параметрыконфигурации РНР определяются в файле php.ini.

safe_mode

Привключении безопасного режима (safe_mode)ограничивается использование некоторыхпотенциально опасных возможностей РНР. Длявключения или выключения безопасногорежима параметру safe_mode присваиваетсязначение on или off. Механизм ограниченияоснован на сравнении идентификаторапользователя (UID) выполняющегося сценария сидентификатором пользователя того файла, ккоторому этот сценарий пытается обратиться.Если идентификаторы совпадают, функциявыполняется; в противном случае попытказавершается неудачей.

Безопасныйрежим не может использоваться в том случае,если РНР откомпилирован в виде модуля Apache.Дело в том, что при работе РНР в режимемодуля Apache все сценарии РНР работают подтем же идентификатором, что и Apache, что непозволяет различать владельцев разныхсценариев. За дополнительной информациейобращайтесь к разделу <Безопасный режим иработа РНР в режиме модуля Apache>.

В частности,при включении безопасного режима действуютследующие ограничения:

  • Функцииввода/вывода (в частности, fopen ( ), filе( ) иinclude ( )) работают только с файлами,принадлежащими владельцу сценария.Предположим, в безопасном режимесценарий, принадлежащий пользователюМэри, вызывает функцию fopen( ). Если функцияпопытается открыть файл, принадлежащийДжону, ее вызов завершится неудачей. Ноесли Мэри принадлежит как сценарий,вызывающий fopen( ), так и открываемый файл,все будет нормально.
  • Запусквнешних сценариев функциями popen( ), system( )или ехес( ) разрешается лишь в том случае,если запускаемый сценарий находится вкаталоге, определяемом параметромsafe_mode_exec_dir (см. далее).
  •  Новыефайлы создаются только в каталогах,принадлежащих владельцу сценария.
  • АутентификацияHTTP становится более жесткой, поскольку вней также учитывается UIDаутентифицирующего сценария. Механизмаутентификации пользователейрассматривается в одном из разделов этойглавы.
  • Имяпользователя, использованное приподключении к серверу MySQL, должносовпадать с именем владельца файла,вызывающего mysql_connect( ).

В табл. 16.1приведен полный список функций, на которыераспространяется безопасный режим.

Таблица16.1. Функции,выполнение которых ограничивается вбезопасном режиме

chgrpincluderequire
chmodlink rmdir
chown passthru symlink
exec popensystem
fopen readfileunlink
filerename

Ксожалению, документация РНР по безопасномурежиму не обновлялась с версии 2.0, хотяфункциональность безопасного режимапрактически не изменилась. Документациянаходится по адресу http://www.php.net/manual/phpfi2.html.

safe_mode_exec_dir

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

disable_functions

В этомпараметре через запятую перечисляютсяимена функций, выполнение которыхтребуется запретить. Обратите внимание -этот параметр никак не связан с safe_mode.Например, чтобы запретить вызовы функцийfopen( ), popen( ) и file( ), достаточно включить вконфигурационный файл следующую строку:

disable_functions =fopen, popen.file

doc_root

Параметруприсваивается путь к корневому каталогудля файлов РНР. Если значение doc_rootпредставляет собой пустую строку, оноигнорируется и сценарии РНР выполняются вполном соответствии с URL. Если безопасныйрежим включен, а параметр doc_root содержитнепустое значение, то сценарии РНР запределами этого каталога выполняться небудут.

max_execution_time

Параметруказывает максимальную продолжительностьвыполнения сценария (в секундах). Поистечении указанного срока сценарийавтоматически завершается, что помогаетбороться с чрезмерными затратамипроцессорного времени на выполнениепользовательских сценариев. По умолчаниюпараметр равен 30 секундам. Если присвоитьему 0, время выполнения сценариев неограничивается.

memory_limit

Параметропределяет максимальный объем памяти (вбайтах), используемой сценарием. Поумолчанию параметр равен 8 Мбайт (8 388 608 байт).

sql.safe_mode

Привключении параметра sql .safejnode игнорируетсявся информация, передаваемая функциямmysql_connect( ) и mysql_pconnect( ), а подключенияразрешаются только для UID, под которымработает web-сервер.

user_dir

Параметропределяет имя подкаталога в домашнемкаталоге пользователя, в котором должнынаходиться исполняемые сценарии РНР.Например, если параметру user_dir присвоенозначение scripts и пользователь с именем Alessiaхочет выполнить сценарий somescript.php, он долженсоздать в своем домашнем каталогеподкаталог с именем scripts и поместитьсценарий в этот каталог. К сценарию можнообратиться по URL http://www.yoursite.com/~alessia/somescript.php.Обратите внимание - каталог scripts в URL невключается. Как правило, этот параметриспользуется в сочетании с параметромконфигурации Apache UserDi г.

Безопасныйрежим и работа РНР в режиме модуля Apache

Следуетпомнить, что при работе РНР в режиме модуляApache безопасный режим недоступен. Этообъясняется тем, что модуль РНР работает всоставе сервера Apache, поэтому все сценарииРНР работают под тем же UID, что и сам серверApache. Поскольку ограничения вызова функций вбезопасном режиме основаны на сравнении UID,этот режим полноценно работает только прииспользовании CGI-версии РНР в сочетании сsuExec (http://www.apache.org/docs/ suexec.html). Дело в том, чтоCGI-версия РНР работает как отдельныйпроцесс, что позволяет динамическиизменять UID средствами suExec. Если васинтересует использование РНР в безопасномрежиме, вероятно, вам следует остановитьсвой выбор на комбинации CGI/suExec, хотя за этоприходится расплачиваться быстродействием.

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

Маскировкафайлов данных и конфигурационных файлов

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

Вконфигурационном файле Apache httpd.confприсутствует параметр DocumentRoot. С его помощьюустанавливается путь к каталогу, которыйрассматривается сервером какобщедоступный каталог HTML. Считается, чтолюбой файл в этом каталоге может бытьпередан в пользовательский браузер, дажеесли расширение этого файла не опознано.Пользователи не могут просматривать файлы,находящиеся за пределами этого каталога.Следовательно, конфигурационные файлы никогдане следует хранить вкаталоге DocumentRoot!

Для примерасоздайте файл и введите в нем какой-нибудь <секретный>текст. Сохраните этот файл в общедоступномкаталоге HTML с именем secrets и каким-нибудьэкзотическим расширением типа .zkgjg.Разумеется, сервер не распознает эторасширение, но все равно попытаетсяпередать запрошенные данные. Теперьзапустите браузер и введите URL со ссылкой наэтот файл. Интересно, правда? К счастью, уэтой проблемы существует два простыхрешения.

Хранениефайлов за пределами корневого каталогадокументов

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

DocumentRoot C:\ProgramFiles\Apache Group\Apache\htdocs # Windows

DocumentRoot /www/apache/home #Другие системы

Предположим,у вас имеется файл с атрибутами доступа (хост,имя пользователя, пароль) к базе данных MySQL.Конечно, этот файл не должен попадаться наглаза посторонним, поэтому вы сохраняетеего вне корневого каталога документов.Например, в системе Windows можновоспользоваться каталогом C:/Program FHes/mysecretdata,а в UNIX - каталогом /usr/local/mysecretdata.

Чтобывоспользоваться атрибутами доступа всценарии, достаточно включить эти файлы суказанием полного пути. Пример для Windows:

INCLUDE("С:/ProgramFiles/mysecretdata/mysqlaccess.inc");

Пример дляUNIX:

INCLUDE("/usr/local/mysecretdata/mysqlaccess.inc");

Конечно, приотключении безопасного режима (см.предыдущий раздел) это не помешает другимпользователям, которые могут выполнятьсценарии РНР, включить этот файл в своисценарии. Следовательно, вмногопользовательской среде эту мерубезопасности желательно сочетать свключением безопасного режима.

Настройкафайла httpd.conf

Во второмварианте доступ к файлам сконфиденциальной информациейограничивается по расширению файла, приэтом используется параметр FILES файла httpd.conf.Допустим, вы хотите запретитьпользователям доступ к файлам срасширением .inc. Для этого достаточновключить в файл httpd.conf следующий фрагмент:

<Files *.inc>

Order allow, deny

Deny from all

</Files>

Послередактирования файла перезапустите серверApache, после этого все попытки запроситьлюбой файл с расширением .inc в браузереотклоняются сервером. Впрочем, эти файлывсе равно могут включаться в сценарии РНР.Кстати говоря, при просмотре файла httpd.conf выувидите, что этот способ применяется дляограничения доступа к файлам .htaccess. Этифайлы используются для парольной защитыкаталогов и рассматриваются в конце главы.

Безопасностьданных

Даже послетого, как вы обеспечили надежнуюконфигурацию сервера, необходимо постояннопомнить о потенциальной угрозе для системыбезопасности, исходящей из программногокода РНР. Не подумайте, что язык РНРнедостаточно надежен - теоретическуюбрешь в системе безопасности можно создатьна любом языке программирования. Тем неменее, учитывая широкое распространениеРНР для программирования в распределенныхсредах с большим количеством пользователей(то есть в Web), вероятность попыток <взлома>ваших программ со стороны пользователейсущественно возрастает. Вы должны самипозаботиться о том, чтобы этого непроизошло.

Обработкапользовательского ввода

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

Простейшийспособ борьбы с потенциально опаснымпользовательским вводом - обработкаполученных данных стандартной функциейescapeshellcmd( ).

escapeshellcmd( )

Функцияescapeshellcmd( ) экранирует все сомнительныесимволы в строке, которые могут привести квыполнению потенциально опасной системнойкоманды:

string escapeshellcmd(stringкоманда)

Чтобы вылучше представили, к каким последствиямможет привести бездумное использованиеполученных данных, представьте, что выпредоставили пользователям возможностьвыполнения системных команд - например, `ls -l`.Но если пользователь введет команду `rm -rf *` ивы используете ее для эхо-вывода иливставите в вызов ехес( ) или system( ), этоприведет к рекурсивному удалению файлов икаталогов на сервере! Проблемы можно решитьпредварительной <очисткой> команды припомощи функции escapeshel lcmd( ). В примере `rm -rf *` послепредварительной обработки функциейescapeshellcmd( ) строка превращается в \ `rm -rf *\`.

Обратныеапострофы (backticks) представляют собойоператор РНР, который пытается выполнитьстроку, заключенную между апострофами.Результаты выполнения направляются прямона экран или присваиваются переменной.

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

strip_tags( )

Функцияstrip_tags( ) удаляет из строки все теги HTML.Синтаксис:

string strip_tags(string строка [, string разрешенные_теги])

Первыйпараметр определяет строку, из которойудаляются теги, а второй необязательныйпараметр определяет теги, остающиеся встроке. Например, теги курсивногоначертания (<1 >...</ 1>) не причинятособого вреда, но лишние табличные теги (например,<td>...</td>) вызовут настоящий хаос.Пример использования функции strip_tags( ):

$input = "I <i>really</i>love РНР!";

$input = strip_tags($input);

// Результат:$input = "I really love PHP!";

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

Шифрованиеданных

Шифрованием называетсяпроцесс преобразования данных в формат, вкотором они могут быть прочитаны (во всякомслучае, теоретически) толькопредполагаемым

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

Общиефункции шифрования

Шифрованиеданных в Web имеет смысл только в том случае,если сценарии, в которых используютсясредства шифрования, работают назащищенном сервере. Почему? Поскольку РНРявляется сценарным языком, работающим настороне сервера, перед шифрованиемданные должны быть отправлены на сервер впростом текстовом формате. Если данныепередаются через незащищенное соединение,существует немало способов перехвата этойинформации в процессе ее пересылки отпользователя на сервер. За дополнительнымисведениями о защите сервера Apacheобращайтесь на сайт http://www.apache-ssl.org.Читателям, работающим с другими web-серверами,следует обращаться к документации. Скореевсего, для этих серверов существует хотя быодно (а может, и больше) решение областибезопасности.

md5( )

Хэширующийалгоритм MD5 используется (в частности) длясоздания цифровых подписей, позволяющиходнозначно идентифицировать отправителя. ВРНР для этого алгоритма существуетспециальная функция

string md5(stringстрока)

MD5 являетсяалгоритмом <одностороннего> хэширования;это означает, что данные, хэшируемыефункцией md5(), восстановить уже невозможно.

Алгоритм MD5также применяется при проверке паролей.Поскольку теоретически невозможновосстановить исходную строку, обработаннуюалгоритмом MD5, можно хэшировать парольфункцией md5( ) и затем сравниватьзашифрованный пароль с результатомобработки пароля, введенного пользователемпри попытке получения доступа кконфиденциальной информации.

Допустим, унас имеется некоторый секретный парольtoystore с хэш-кодом 745e2abd7c52eeldd7cl4aeOd71b9d76.Хэшированное значение сохраняется насервере и сравнивается с хэш-эквивалентомпароля, введенного пользователем. Даже еслизлоумышленник получит доступ кзашифрованному паролю, это ни на что неповлияет, поскольку он (теоретически) несможет восстановить по нему оригинал.Пример хэширования строки:

$val = "secret";

$hash_val = md5 ($val);

// $hash_val ="Clab6fb9182fl6eed935bal9aa830788";

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

crypt( )

Функция crypt( )является удобным средством дляодностороннего шифрования данных. Под <одностороннимшифрованием> я подразумеваю, что данныемогут толькошифроваться - алгоритмы для расшифровкиданных, обработанных функцией crypt( ), поканеизвестны. Синтаксис:

string cкypt(stringстроке [, детерминант])

Первыйпараметр определяет строку, шифруемуюфункцией crypt( ). Необязательный второйпараметр определяет алгоритм, используемыйпри шифровании. Точнее, тип алгоритмаопределяется длиной детерминанта.Различные типы алгоритмов и длины ихдетерминантов перечислены в табл. 16.2.

Таблица16.2. Алгоритмышифрования и длины их детерминантов

АлгоритмДлина
CRYPT_STD_DES2
CRYPT_EXT_OES9
CRYPT_MD512
CRYPT BLOWFISH16

В листинге16.1 продемонстрировано использованиефункции crypt( ) для создания и сравнениязашифрованных паролей.

Листинг16.1. Применениефункции crypt (STD_DES) для хранения и сравненияпаролей <?

<?

$user_pass ="123456";

// Выделитьпервые два символа $user_pass

// и использоватьих в качестве детерминанта.

$salt = substr($user_pass. 0,2);

//Зашифровать и сохранить пароль.

$crypt1 = crypt($user_pass,;salt);

// $crypt1 = "12tir.zIbWQ3c"

//... пользовательвводит пароль

$entered_pass = "123456";

// Получитьпервые два символа хранящегося пароля

$salt1 =substr($crypt, 0, 2);

//Зашифровать $entered_pass, используя $saltl вкачестве детерминанта.

$crypt2 = crypt($entered_pass,$salt1);

// $crypt2 = "12tir.zIbWQ3c";

//Следовательно. $cryptl = $crypt2

?>

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

Как видноиз листинга 16.1, $crypt совпадает с $crypt2, но толькопотому, что мы правильноиспользовали первые два символа $crypt1 вкачестве детерминанта для шифрования$entered_pass. Поэкспериментируйте с этимпримером, попробуйте использоватьразличные значения, и вы убедитесь, что $crypt1совпадает с $crypt2 лишь при использованииэтой процедуры.

mhash( )

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

  1. Зайдите насайт http://mhash.sourceforge.netи загрузите пакет.
  2. Распакуйтесодержимое архива и выполните инструкции,приведенные в документе INSTALL.
  3. Откомпилируйте РНР с ключом -with-mhash.

Как видите,ничего сложного. Впрочем, имеется однообстоятельство, которое часто вызываетпроблемы при компиляции mhash для комбинацииРНР/Apache, - многим пользователям приходитсяконфигурировать mhash следующим образом: "./configure -disable -pthreads" (вы поймете, о чем идетречь, если прочитаете документ INSTALL).Помните об этом в процессе компиляции.

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

Таблица16.3. Алгоритмыхэширования, поддерживаемые mhash( )

SHA1RIPEMD160MD5
GOST TIGERSNEFRU
HAVALCRC32
RIPEMD128
CRC32B

mcrypt( )

Mcrypt -популярный пакет шифрования данных в РНР,обеспечивающий возможность двустороннегошифрования (то есть собственно шифрование ирасшифровку данных). Четыре режимашифрования, поддерживаемых модулем mcrypt,перечислены ниже.

CBC

Режим СВС (CipherBlock Chaining) является самым распространеннымиз всех четырех режимов mcrypt. В отличие отрежима ЕСВ (см. ниже), СВС обеспечиваетразное шифрование идентичных блоков текста,что затрудняет поиск закономерностей припопытке несанкционированной расшифровки.Если вы не знаете, какой из четырех режимовследует использовать, выбирайте СВС.Впрочем, перед принятием окончательногорешения стоит ознакомиться со всемичетырьмя режимами.

СFВ

Режим СFВ (CipherFeedback) обладает некоторыми характеристикамипотоковых шифров, что избавляет отнеобходимости накопления блоков данныхперед шифрованием. Данный режимиспользуется очень редко.

ЕСВ

Режим ЕСВ (ElectronicCode Book) шифрует каждый текстовый блокнезависимым блочным шифром, что несколькоснижает его защищенность при шифрованииотносительно малых блоков обычного текста.Поскольку ЕСВ шифрует два блока простоготекста одинаковым шифром, у злоумышленникапоявляется основа для расшифровки.Следовательно, если у вас нет вескихдоводов в пользу ЕСВ, вероятно, лучшевоспользоваться режимом СВС.

OFB

По многимхарактеристикам режим OFB (Output Feedback) похож нарежим СFВ. Как и СFВ, он используетсяотносительно редко.

Чтобывоспользоваться средствами mcrypt необходимопредварительно принять па-кет по адресу ftp://argeas.cs-net.gr/pub/unix/mcrypt.

Дополнительнаяинформация

В этомразделе описаны лишь те средства, которые втой или иной степени интегрируются в РНР.Впрочем, этим ваши возможности неограничиваются. Помните о том, что припомощи функций рореn( ) или ехес( ) можноработать с любыми технологиями шифрования,разработанными независимыми фирмами, -например, PGP (http://www.pgpi.org) или GPG(http://www.gnupg.org).

Нижеперечислены некоторые ресурсы Интернета,посвященные криптографии и информационнойбезопасности:

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

Электроннаякоммерция

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

Verisign

КомпанияVerisign, Inc. (http://www.verisign.com) предоставляетширокий ассортимент коммерческихпродуктов и услуг. В РНР предусмотренаподдержка взаимодействия со службой VerisignPayflow Pro.

Дляиспользования средств Verisign РНР необходимооткомпилировать с ключом -with-pfproC-DIR]. Крометого, в файле php.ini имеется несколькоконфигурационных параметров, относящихся кPayflow Pro.

ПоддержкаPayflow Pro в РНР очень проста в использовании, анепосредственное проведение сделоктребует минимальных времени и знаний.Однако простое включение поддержки Verisignпри компиляции РНР вовсе не означает, что выможете пользоваться услугами Verisign! Дляэтого необходимо предварительнозарегистрироваться на сайте Verisign и принятьпакет Verisign SDK. На момент написания книги заподключение к Payflow Pro взимался разовый взнос$249, а также ежемесячная оплата $59.95 (еслиежемесячное количество сделок не превышает5000) или $995 (при неограниченном количествесделок).

И еще однозамечание: прежде чем оплачивать услугиVerisign, вы можете протестировать свойсценарий при помощи тестового входа (этууслугу Verisign предлагает бесплатно).Бесплатное тестирование сценариев избавитвас от лишних расходов в процессе отладкипрограмм. Дополнительную информацию можнополучить на сайте Verisign.

РесурсыИнтернета, посвященные Verisign:

Cybercash

КомпанияCybercash, Inc. (http://www.cybercash.com) предлагаетразнообразные услуги по проверке кредитныхкарт и проведению сделок, а такжепрограммное обеспечение для тех, кто желаетиспользовать эти услуги в своих web-приложениях.

Сценарии,написанные на Perl, могут взаимодействоватьсо службой проведения сделок Cybercash.Учитывая это обстоятельство, пользователиРНР обычно интегрируют Cybercash со своимисайтами одним из следующих способов:

  • Используябиблиотеку cyberlib.php, включенную в поставкуРНР. Этот вариант предоставляет в вашераспоряжение все необходимое дляпроведения транзакций (рекомендуется).
  • Взаимодействуясо службой Cybercash при помощи готовыхсценариев Perl и С и вызывая их из сценариевРНР (рекомендуется).
  • Переписываяготовые сценарии Perl и С на РНР (нерекомендуется).

Дляиспользования средств Cybercash РНР необходимооткомпилировать с ключом -with-cybercash[=DIR].

Как и вслучае с Verisign, помните, что включениеподдержки Cybercash при компиляции РНР еще неозначает, что вы можете пользоваться этойслужбой! Услуги Cybercash не бесплатны и могутобойтись довольно дорого (подключение кслужбе Cybercash Commerce Cash Register в настоящее времястоит $495, ежемесячная оплата составляет $20,а каждая сделка стоит $0,20). Тем не менее,невзирая на все расходы, многиеразработчики РНР считают, что Cybercashявляется одним из лучших решений.

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

РесурсыИнтернета, посвященные Cybercash:

CCVS

ТехнологияCCVS (Credit Card Verification System) была разработана RedHat (http://www.redhat.com)для независимой обработки сделок покредитным картам. Она позволяет напрямуюобращаться к агентствам кредитных картвместо того, чтобы пользоваться услугамитретьих сторон (например, Cybercash). ТехнологияCCVS совместима со многими платформами Linux/UNIXи легко адаптируется, поскольку RedHatпредоставляет исходные тексты.

Дляиспользования средств CCVS РНР необходимооткомпилировать с ключом-with-ccvs[-DIR].

Задополнительной информацией о CCVSобращайтесь по адресам:

Аутентификацияпользователя

Правильновведенные имя и пароль открываютпользователю доступ к каталогам сервера,недоступным для анонимного доступа. Этотпринцип аутентификации обычно называетсясхемой <запрос/ответ> (challenge/response). Запросомявляется приглашение к вводу имени и пароля,а ответом - введенные данные. Есливведенная комбинация верна, пользователюпредоставляется доступ к защищеннымкаталогам; в противном случае попыткаполучения доступа отклоняется с выводомсоответствующего сообщения.

Как правило,для ввода имени и пароля применяютсядиалоговые окна, активизируемые вызовомфункции header( ) (листинг 16.2).

Листинг16.2. Запросданных для аутентификации пользователя <?

<?

header( 'WWW-Authenticate:Basic realm="Secret Family Recipes"');

header ('HTTP/1.0 401Unauthorized');

exit;

?>

Выполнениефрагмента из листинга 16.2 всего лишьактивизирует окно для ввода данных.Примерный вид этого окна изображен на рис.16.1.

 

Рис. 16.1. Окноаутентификации пользователя

Следующимшагом после подготовки интерфейса дляввода является обработка именипользователя и пароля. В РНР имя и парольхранятся в двух глобальных переменных,$PHP_AUTH_USER (имя) и $PHP_AUTH_PW (пароль). В листинге 16.3показано, как проверяются значения этихпеременных. Если данные не были введены,окно аутентификации отображается заново.

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

Листинг16.3. Проверкаглобальных переменных аутентификации в РНР

<?

If ( (! isset ($PHP_AUTH_USER))|| (! isset ($PHP_AUTH_PW)) ):

headert 'WWW-Authenticate:Basic realm="Secret Family Recipes'");

header(''HTTP/1.0 401Unauthorized');

print "You areattempting to enter a restricted area. Authorization is required.";

exit;

endif;

?>

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

Листинг16.4. Жесткоекодирование имени и пароля в сценарии

<?

if ( (! isset ($PHP_AUTH_USER))| (! isset ($PHP_AUTH_PW)) || ($РНР AUTH USER != 'secret') | ($PHP_AUTH_PW !-'recipes') ) :

header('WWW-Authenticate:Basic realm="Secret Family Recipes'"); header('HTTP/1.0 401Unauthorized');

print "You areattempting to enter a restricted area. Authorization is required,

exit;

endif;

?>

Аутентификацияс несколькими пользователями

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

Хранениеинформации в текстовом файле

Существуеточень простое, но эффективное решение -хранить аутентификацион-ные данные втекстовом файле. В каждой строке файласодержится отдельная пара <имя:пароль>; в,процессепроверки программа последовательно читаети проверяет все строки файла. Примерный видтекстового файла приведен в листинге 16.5.

Листинг16.5. Типичныйтекстовый файл с параметрамиаутентификации (authenticate.txt)

brian:snaidni00

alessia:aiggaips

gary:9avaj9

chris:poghsawcd

matt:tsoptaes

Как видно излистинга, каждая строка приведенного файласостоит из имени пользователя и пароля,разделенных двоеточием (:). Таким образом,при использовании этого файла существуетпять комбинаций <имя/пароль>,обеспечивающих доступ к ограниченнымресурсам. Каждый раз, когда пользовательвводит имя и пароль в окне, сценарийоткрывает текстовый файл и последовательноищет в нем совпадающую пару. Еслисовпадение находится, запрашиваемый доступпользователю предоставляется, а если нет -запрос отклоняется. Процедурааутентификации продемонстрирована влистинге 16.6.

Листинг16.6. Аутентификацияна основе текстового файла <?

<?

$file ="Listing16-5.txt":

$fp = fopen($file,"r"):

$auth_file = fread ($fp,filesize($fp)):

fclose($fp);

$authorized = 0;

// Сохранитьстроки файла в виде элементов массива

$elements= explode ("\n", $auth_file);

foreach ($elements as$element) {

list ($user, $pw) =split (":", $element);

if (($user ==$PHP_AUTH_U$ER) && ($pw = $PHP_AUTH_PW)) :

$authorized = 1;

break ;

endif;

}

if (! $authorized) :

header('WWW-Authenticate:Basic realm="Secret Family Recipes'");

header('HTTP/1.0 401Unauthorized');

print "You areattempting to enter a restricted area. Authorization is required.";

exit;

else :

print "Welcome tothe family's secret recipe collection";

endif;

?>

Хранениеинформации в базе данных

Хранениеаутентификационной информации в базахданных обладает рядом преимуществ, многиеиз которых рассматривались в главе 11.Простота обновления, масштабируемость игибкость - лишь некоторые из доводов впользу хранения больших объемов информациив базе данных. В табл. 16.4 приведеносодержимое демонстрационной таблицыuser_authenticate. После успешно пройденнойаутентификации по идентификаторупользователя можно устанавливать связи сдругими таблицами, содержащимиразнообразные данные и настройки. Процессразделения взаимосвязанных данных потаблицам меньшего размера (вместогруппировки всей информации в однойбольшой таблице) называется нормализациейбазы данных, о нем краткоговорилось в главе 11.

Впримерах этого раздела используетсясинтаксис MySQL. Программный код достаточнопрост и легко адаптируется для других СУБД.

Таблица16.4. Примертаблицы с аутентификационными данными (user_authenticate)

userid

username

password

url234

brian

2b877b4b825b48a9a0950dd5bdlf264d

urlHS

alessia

6fled002ab5595859014ebf0951522d9

url15932

gary

122a2aladf096fe4f93287f9dal8f664

url19042

chris

6332e88a4c7dba6f7743d3a7a0c6ea2c

url8930

matt

922fe5dl40el9d308f2037404a0536a

Программа,приведенная в листинге 16.7, сначалапроверяет, было ли присвоено значениепеременной $PHP_AUTH_USER. Если значение неприсвоено, выводится окно для вводанеобходимой информации. В противном случаепрограмма создает соединение с сервером MySQLи ищет в таблице user_authenticate имя и пароль,введенные пользователем. При отсутствиисовпадения окно аутентификации выводитсязаново, а если проверка дает положительныйрезультат, переменной $user_id присваиваетсяидентификатор пользователя.

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

<?

if (!isset($PHP_AUTH_USER)):

header( 'WWW-Authenticate:Basic realm="Secret Family Recipes'");

header('HTTP/1.0 401Unauthorized');

exit;

else :

// Создатьсодинение с базой данных MySQL

mysql_connect ("host","user", "password")

or die ("Can'tconnect to database!");

mysql_select_db ("useMnfo")

or die ("Can'tselect database!");

// Обратитьсяк таблице user_authenticate

// для поискасовпадающей строки

$query = "select userid fromuser_authenticate where

username = '$PHP_AUTH_USER'and

password = '$PHP_AUTH_PW'";

$result = mysql_query (Squery):

// Еслисовпадение не найдено, вывести окноаутентификации

if (mysql_numrows($result) != 1) :

header('WWW-Authenticate:Basic realm="Secret Family Recipes'");

header ('HTTP/ 1.0 401Unauthorized');

exit;

// Еслипроверка пройдена, получить идентификаторпользователя

else ;

Suserid = mysql_result(user_authenticate, 0, $result);

endif;

endif;

?>

Итоги

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

  • проблемыконфигурации РНР;
  • безопасныйрежим;
  • проблемыпрограммирования;
  • шифрованиеданных;
  • технологииэлектронной коммерции;
  • аутентификацияпользователей.

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