print “Welcome $uname!”;
# do stuff as $uname
} else {
print “Error: not authenticated”;
}
Хотя это решение и выглядит правильным (в фрагменте кода выполняется проверка того, что значение параметра authkey начинается со строки символов, совпадающих со значением параметра uname), но оно ошибочно. В фрагменте кода проверяется только то, что параметр authkey начинается со значения параметра uname. Это значит, что если значение authkey было бы «rfp.234623.temp», то можно было бы использовать в качестве значения параметра uname символ «r», так как строка «rfp» начинается с символа «r». Ошибка исправляется заменой $authkey=~/^$uname/ íà $authkey=~/^$uname\./. В результате выполняется проверка на совпадении всего значения первой части параметра authkey с uname. PacketStorm решил использовать вариант, похожий на следующий:
@authkey_parts = split(“.”, $authkey);
if ($authkey_parts[0] eq $uname && -e «authkey_directory/
$authkey»){ …,
Приведенный вариант – всего лишь иной способ убедиться в совпадении значения первой части параметра authkey со значением uname. Но все равно в демонстрационном коде присутствуют погрешности. Зачем дублировать и сравнивать имя пользователя параметра authkey со значением uname? Оно всегда должно быть одним и тем же. Храня его в двух местах, всегда существует вероятность ошибок. Корректнее использовать следующий код:
if (-e «authkey_directory/$uname.$authkey.temp»){...
В этом случае следует лишь переслать URL:
authkey=234562&uname=rfp.
В новом варианте программы имя файла «rfp.234562.temp» собирается из двух половинок. Тем самым гарантируется, что в приложении будет использовано одно и то же имя пользователя, совпадающее со значением параметра uname, и что атакующий может ссылаться только на файлы с расширением имени «.temp», поскольку так определено в программе. Тем не менее возможны и другие трюки злоумышленника. Например, передача символа NULL в конце значения параметра authkey вынудит систему проигнорировать добавление строки «.temp». Этого можно избежать, убрав все NULL из переданной строки. Но злоумышленник может использовать для аутентификации любой известный. temp-файл с помощью символов «../» в совокупности с другими хитростями. Поэтому лучше убедиться, что параметр $uname содержит только допустимые символы (предпочтительно лишь буквы), а $authkey – только числа. В общем случае для аутентификации лучше использовать запросы SQL к базе данных пользователей и паролей. Например, следующий запрос:
SELECT * FROM Users WHERE Username=’$name’ AND Password=’$pass’,
где $name и $pass – параметры имя пользователя и его пароль. В результате выполнения запроса будут найдены все записи в базе данных, у которых имя пользователя и пароль совпадают со значениями параметров, введенными пользователем. Полученный результат может быть обработан следующим образом:
if ( number_of_return_records > 0) {
# username and password were found; do stuff
} else {
# not found, return error
}
Приведенный фрагмент программы обрабатывает результат запроса. Если в результате запроса были найдены записи, то введенная пользователем комбинация из имени пользователя и его пароля действительна. Тем не менее это образец небрежного программирования, основанного на ошибочном предположении. Представьте, что злоумышленник передаст в качестве параметра $pass следующее значение:
boguspassword OR TRUE
В результате злоумышленник будет аутентифицирован как законный пользователь, потому что в ответ на запрос будут найдены все записи базы данных, а согласно логике приложения при нахождении хотя бы одной записи, удовлетворяющей запросу, полномочия пользователя считаются подтвержденными.
Ошибка заключается в логическом условии (при number_of_return_records > 0). Это условие предполагает наличие ситуации, при которой одной комбинации имени пользователя и его пароля соответствуют многочисленные записи в базе данных. В правильно разработанном приложении подобная логическая ошибка должна быть исправлена. Исправленное логическое условие должно быть таким: (number_of_return_records == 1). Потому, что если число записей равно нулю, то в результате запроса не было найдено ни одной записи с заданной комбинацией имени пользователя и пароля, что свидетельствует о неуспешном завершении процедуры аутентификации. Одна найденная запись говорит об успешном завершении процедуры аутентификации, а более одной – о наличии проблемы из-за ошибки работы с базой данных или атаки злоумышленника.
Конечно, из-за взятого в кавычки параметра
$passописанная только что ситуация может не произойти. Результат непосредственной подстановки значения параметра в запрос будет выглядеть так:
… AND Password=’boguspassword OR TRUE’
Читать дальше
Конец ознакомительного отрывка
Купить книгу