Защита веб-приложений на Perl - страница 8
Кривые скрипты по соседству могут свести на нет все ваши старания. Например, форум стороннего производителя. Скажем, в нём нашли уязвимости, а вы обратили внимание о новости слишком поздно – это угроза. Либо галерея картинок, писаная начинающими ради уникальных фич, но без полноценного учёта безопасности – тоже яркий пример. Если ваш проект настолько крут и важен, что вы боитесь за него из-за соседей на shared-хостинге, просто возьмите себе VPS или даже DS. Тогда вас будет труднее положить, у вас будет больше производительности и не будет таких соседей, которых стоит бояться на shared-хостинге.
К младшему брату, языку PHP, существует интересный патч под названием suhosinhttp://www.hardened-php.net/suhosin/. Он добавляет к языку довольно мощные инструменты защиты скриптов. Прочитайте список возможностейhttp://www.hardened-php.net/suhosin/a_feature_list.html. Это превосходный источник идей, которые вы можете реализовать на Perl для защиты собственных проектов.
Существует опасность при появлении NULL-байта в строке, полученной от пользователя. Это символ, числовой код которого равен нулю. Сразу же приведу пример, где это очень наглядно видно:
Когда пользователь передал в программу на Perl строку, в середине которой имеется нулевой байт, вся строка попадает в переменную как есть. То есть всё, что идёт до нулевого байта, сам нулевой байт и всё, что после, будет сохранено в строке. Как только вы попытаетесь открыть файл с именем, хранящемся в такой переменной, нулевой байт будет означать конец строки, потому что Perl написан на языке C, а для языка C нулевой байт – это как раз символ окончания строки. Поэтому имя открываемого файла в конечном счёте будет воспринято внутренней сишной природой перла как строка до нулевого байта, остаток байт в перловой строке будет проигнорирован.
Представьте себе, что вы написали защиту, которая опирается на проверку строки от пользователя с помощью регулярного выражения. Вы хотите, чтобы это был исключительно текстовый файл. Вы сравниваете строку с выражением /\.txt$/ и считаете, что на этом задача решена. Однако пользователь может передать вам строку ”config.pl\x00.txt“. Такая строка пройдёт проверку, ведь у неё в конце по версии перлового представления строк есть фрагмент .txt, а какой файл откроется на самом деле, вы уже догадались? :)
Уязвимость чинится очень просто: как только вам передали имя файла, нулевой байт вырезается ($str =~ s/\0//g;) а лучше сразу фильтровать всё, кроме алфавитно-цифровых символов, точек, минусов, подчёркиваний, словом, всего того, из чего может состоять имя файла, который допустимо открыть.
-T
Не доверять пользователю. Если вы попытаетесь использовать данные от пользователя напрямую (Cookie, переменные окружения, параметры, переданные по CGI, ввод с клавиатуры и т.п.), Perl выдаст предупреждение о том, что такие данные требуется отфильтровать. Например, с помощью регулярного выражения выполняется извлечение, и только использование результата такого извлечения пройдёт без предупреждения.
-w
Показывать предупреждения о проблемах, которые не фатальны, с которыми скрипт работать будет, но обратить внимание на которые стоит как с точки зрения аккуратного программирования, так и с точки зрения безопасности. Одно из самых полезных предупреждений, на мой взгляд, использование переменной, которой ничего не присвоено, то есть то же, что и undef. Проверить неопределённость переменной можно так: >defined($var)
. Когда вы добьетесь чистого выполнения скрипта без предупреждений с ключом -w в самых разных условиях, которые только сумеете придумать, вы как минимум теоретически усилите безопасность скрипта.
-W
То же, что и -w, только Perl покажет больше предупреждений, часть из которых совсем уж незначительна. Например, часто можно видеть, как при -W Perl ругается даже на собственные модули из коробки! Это, безусловно, отвлекает. С этим особо нечего поделать. Тут придётся либо на время наведения железного порядка у себя в скрипте смириться и игнорировать их, либо принять участие в улучшении чужого модуля – сообщество программистов будет вам признательно :) Только перед тем, как чинить чужое, убедитесь что у вас именно последняя версия модуля.