В результате многие CGI-сценарии пишутся с использованием более защищенных окружений, например сценарии на языке Perl, которые выполняются интерпретатором, запущенным с флагом −w в строке shebang (#! в первой строке сценария), прерывающим работу сценария при попытке использовать внешние данные без дополнительной очистки или проверки.
Хотя механизмов поддержки безопасности в сценариях командной оболочки недостаточно, это не мешает гарантировать безопасную работу в Интернете. Достаточно лишь понимать, где могут возникнуть проблемы, и поставить заслон у них на пути. Например, показанное в листинге 8.2 небольшое изменение способно обезопасить сценарий в листинге 8.1 от злоумышленников, пытающихся совершить проникновение с помощью специально сформированных данных.
Листинг 8.2.Отправка электронной почты с помощью флага −t
(echo "Subject: Thanks for your signup"
··echo "To: $email ($name)"
··echo ""
··echo "Thanks for signing up. You'll hear from us shortly."
··echo "- Dave and Brandon"
) | sendmail −t
Флаг −t сообщает программе sendmail, что она должна проанализировать само сообщение и извлечь адрес получателя из него. Строка в обратных апострофах никогда не увидит свет командной строки, потому что система анализа в sendmail интерпретирует ее как недействительный адрес. Такое послание будет безопасно сохранено в вашем домашнем каталоге, в файле dead.message , и зарегистрировано в системном журнале.
Другая мера предосторожности заключается в кодировании информации, посылаемой из веб-браузера на сервер. Кодированный обратный апостроф, например, мог бы быть отправлен на сервер (и обработан CGI-сценарием) как последовательность символов %60, не представляющая никакой опасности.
Одной общей характеристикой всех CGI-сценариев в этой главе является использование очень, очень ограниченного декодирования зашифрованных строк: пробелы кодируются для передачи знаком +, а значит, безопасно преобразуются обратно. То же касается символа @ в адресах электронной почты, который передается как последовательность %40. В остальных случаях строку можно безопасно проверить на присутствие символа % и сгенерировать ошибку, если он встретится.
Конечно, сложные веб-сайты используют более надежные инструменты, чем командная оболочка, но, как показывают многочисленные примеры в этой книге, часто для проверки идеи или решения проблемы быстрым, переносимым и достаточно эффективным способом, двадцати-, тритдцатистрочных сценариев командной оболочки оказывается вполне достаточно.
Запуск сценариев из этой главы
Чтобы запустить любой из представленных в этой главе CGI-сценариев на языке командной оболочки, требуется нечто большее, чем просто ввести код и сохранить файл. Нужно также поместить сценарий в правильное место, определяемое конфигурацией действующего веб-сервера. Кроме того, нужно установить веб-сервер Apache с помощью системного диспетчера пакетов и подготовить его к выполнению новых CGI-сценариев. Ниже показано, как это сделать с помощью диспетчера пакетов apt:
$ sudo apt-get install apache2
$ sudo a2enmod cgi
$ sudo service apache2 restart
Установка с помощью диспетчера пакетов yum выполняется аналогично:
# yum install httpd
# a2enmod cgi
# service httpd restart
После установки и настройки можно приступать к разработке сценариев в каталоге по умолчанию cgi-bin для конкретной операционной системы (/ usr/lib/cgi-bin/ в Ubuntu или Debian и /var/www/cgi-bin/ в CentOS) и просматривать результаты их выполнения в веб-браузере, вводя адрес http:///cgi-bin/script.cgi. Если в окне браузера отображается исходный код сценария, установите для него право на выполнение командой chmod +x script.cgi.
№ 63. Обзор CGI-окружения
В то время как мы разрабатывали сценарии для этой главы, компания Apple выпустила новую версию веб-браузера Safari. У нас сразу возник вопрос: «Как Safari идентифицирует себя в строке HTTP_USER_AGENT?» Ответ на него легко получить с помощью CGI-сценария на языке командной оболочки, представленного в листинге 8.3.
Листинг 8.3.Сценарий showCGIenv
··#!/bin/bash
··# showCGIenv — выводит CGI-окружение, которое получает любой
··#·· CGI-сценарий в этой системе.
··echo "Content-type: text/html"
··echo ""
··# Вывести фактические сведения…
··echo "
CGI Runtime Environment
"
··echo "
"
··env || printenv
··echo "
"
··echo "
Читать дальше