char buff [4096];
int length = atoi(getenv("CONTENT_LENGTH"));
fread(buff, 1, length, stdin);Возможное переполнение буфера налицо. Справиться с этой проблемой очень легко – достаточно динамически выделить буфер требуемой длины:
int length = atoi(getenv(«CONTENT_LENGTH»));
char* buff = new char[length];
if(buff)
fread(buff, 1, length, stdin);Потенциально опасны многие строковые функции, определяющие конец строки по завершающему нулю. Поэтому вместо функций strcpy, strcat, strcmp и т. п. настоятельно рекомендуется использовать их аналоги strncpy, strncat, strncmp, позволяющие указать максимальное количество обрабатываемых символов.
Казалось бы, можно ограничить объем вводимой информации указанием соответствующих параметров в тэгах формы, но это еще одно очень опасное заблуждение, которого мы коснемся чуть позже.
Возможно, именно из-за необходимости постоянно контролировать размер буфера многие начинающие (и не только) CGI-программисты предпочитают Perl.
Во-вторых, следующий большой класс ошибок связан с вызовом внешних программ. Здесь Perl предоставляет больше шансов для случайной ошибки – в то время как у С++ с этой точки зрения потенциально опасны функции popen и system (причем вместо последней часто можно безболезненно воспользоваться exec или spawn), у Perl проблемными считаются функции system и exec, open с перенаправлением вывода (аналогичная popen), функция eval, а также обратная кавычка «`».
Сами по себе перечисленные функции достаточно безопасны, и, если скрипт просто вызывает некую внешнюю программу, никакой беды в этом нет. Сложности возникают, когда скрипт передает внешней программе в качестве параметра некую информацию, введенную пользователем: адрес, сообщаемый программе электронной почты, вызов grep из поисковой системы и т. д. Если в процессе вызова внешней программы будет участвовать командная оболочка, как это происходит при использовании перечисленных функций, то можно воспользоваться ее управляющими символами и выполнить на сервере любую команду.
Очевидный пример – отправление письма по адресу, указанному пользователем (например, в качестве подтверждения какого-то запроса и т. п.):#!/usr/bin/perl
use CGI qw(:standard);
$query = new CGI;
$mailprog=’| /usr/sbin/sendmail’;
$address= $query->param(’address’);
$from=’webmaster@somehost’;
open (MAIL,"$mailprog $address");
print MAIL "From: $from\nSubject: Confirmation\n\n";
print MAIL "Your request was successfully received\n";
close MAIL;Теперь предположим, что пользователь ввел следующий обратный адрес: [email protected];mail [email protected] Кроме того, при этом вполне может быть использована какая-нибудь недокументированная команда или люк, позволяющие выполнить код от имени привилегированного пользователя.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии