Примеры программ на Perl

Огромное количество CGI-сценариев на языке Perl уже доступно в Интернете и готово к использованию. Вот список нескольких полезных источников (проверяйте каждый такой сценарий на защищенность, а также на предмет наличия любых других проблем):

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

Защита CGI.

Обеспечение безопасности всегда было серьезной проблемой. В наши дни она еще более актуальна, так как но мере развития операционных систем становится все сложнее и сложнее затыкать бреши в защите. Поэтому на Unix-системах CGI-сценарии обычно запускаются от имени идентификатора пользователя "nobody" («никто»). Такой процесс имеет минимум привилегий. Считалось, что процесс, имеющий минимум привилегий, принесет меньше вреда. Однако и по сей день могут возникать проблемы — в частности, из-за неаккуратности в CGI-сценариях. Ниже рассказывается, как обойти некоторые наиболее вероятные неприятности.

Вот несколько Web-страниц, посвященных безопасности CGI, которые я рекомендовал бы прочитать до того, как вы начнете создавать для широкого использования что-либо серьезнее простейших CGI-сценариев:

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

Серьезно беремся за защиту.

CGI-сценарии могут порождать множество потенциальных брешей в безопасности. В качестве предельного случая рассмотрим сценарий, запускающий программы, имена которых передаются ему в качестве аргумента. Данные форм HTML посылаются в виде строк, причем в качестве разделителя аргументов используется вопросительный знак. Строка данных записывается в конце URL, что означает, что если вы хотите просто запустить сценарий Perl, URL должен выглядеть, например, так:

http://www yourserver.com/user/perl.exe?script.pl

Но если хакер увидит, что вы используете технику вроде этой, он может послать собственную строку такого вида:

http://www.yourserver.com/user/perl.exe?-e+ nasty commands

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

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

На самом деле в Perl существует прекрасный механизм безопасности, предназначенный для латания дырок подобного типа, —меченые данные. Если разрешено отслеживание данных, Perl не позволяет передавать пришедшие извне данные функциям system, ехес и т. д. Простое правило, позволяющее обеспечить безопасность, — никогда не передавать непроверенные данные внешней программе и всегда стараться обойтись без запуска командной оболочки.

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

&;''\"*?`<>^(){}$\n\r

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

И, конечно же, обычные ограничения: не посылайте пароли по электронной почте, не набирайте их при работе с бесплатными утилитами. He оставляйте ваш счет в системе (account) на долгое время неиспользуемым — хакеры следят за такими вещами, чтобы получить контроль над ними. Не позволяйте CGI-сценариям получать слишком много системной информации. И так далее, и тому подобное — большинство хакеров пролезут там, где вы и не думали.

Работаем с мечеными данными.

Одной из самых больших дыр в защите CGI-сценариев является передача непроверенных данных командному интерпретатору. В Perl для предотвращения таких ситуаций можно использовать механизм меченых данных (tainted data). В этом случае любые переменные, связанные с данными, полученными извне (включая переменные среды, стандартный поток ввода и командную строку), считаются мечеными. Пока они остаются таковыми, их нельзя использовать для чего бы то ни было за пределами вашей программы. Если меченая переменная используется для установки другой переменной, последняя также становится меченой, что означает, что помеченные (или «запачканные») данные могут распространяться по программе сколь угодно далеко и сколь угодно сложными путями, но они все равно будут аккуратно помечены.

Подсказка. Этот механизм работает только для скалярных значений. Некоторые элементы массива могут быть мечеными, в то время как остальные — нет.

В общем, меченые данные не могут быть использованы при помощи вызовов eval, system, exec. Perl следит за тем, чтобы они не попали в команды, вызывающие оболочку, в команды, модифицирующие файлы, каталоги или процессы. Однако есть одно важное исключение: если вызовам system или eval передается список аргументов, он не проверяется на наличие меченых элементов. Если вы попробуете произвести какую-либо операцию с мечеными данными за пределами программы, Perl остановится с предупреждающим сообщением. В ре¬жиме меченых данных Perl прекращает работу также в случае вызова внешней программы без предварительной установки переменной среды PATH. В Perl версии 4 для включения отслеживания меченых данных используется специальная версия интерпретатора, называемая taintperl:

#!/usr/local/bin/taintperl

Однако в версии 5 проверка меченых данных включена в состав Perl, и вы можете включить ее, передав интерпретатору Perl ключ -T:

#!/usr/local/bin/perl -T

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

#!/usr/local/bin/perl -T

print "Hello!\n";

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

#!/usr/local/bin/perl -Т 
print system( 'date');
Insecure $ENV(PATH) while running with -T switch at taint.pl 
line 5, <> chunk 1

Чтобы исправить это, вы можете при включенной проверке меченых данных са¬мостоятельно установить $ENV{'PATH'}:

#!/usr/local/bin/perl -T
$ENV{'PATH'} = '/bin:/usr/bin:/usr/1ocal/bin';
print system('date'), 
Thu Nov 12 19-55 53 NSK

Вот еще пример, в котором делается попытка передать системному вызову меченые данные. Даже если $ENV{'PATH'} устанавливается в программе, сценарий все равно прекращает работу, так как пытается передать меченые данные оператору system:

#!/usr/local/bin/perl -T
$ENV{'PATH'} = /bin:/usr/bin:/usr/local/bin';
while(<*gt) {
$command = $_;
system($command); }
Insecure dependency in system while running with -T switch at taint.pl line 5, <*GT chunk 1

Данные, даже будучи переданными в $command из $_, все равно считаются мечеными. Как очистить данные, если вы уверены в них?

Hosted by uCoz