Forum Webscript.Ru
Программирование => Perl => Тема начата: Kwazar от 13 Февраля 2003, 13:28:09
-
Сделал систему увторизации. проблемма в том - что она подрузомевает 3 рода прав и огромное количество (более 10 000) пользователей.
Пожалуйства проверте этот скрипт на вломоустоичивость, подскажите, может стоит что-то изменить?
Вот код:
sub aut {
########получаем куки
@cookies = split (/\\; /,$ENV{HTTP_COOKIE});
foreach $cookies (@cookies)
{
($n, $value) = split(/=/, $cookies);
$n =~ tr/+/ /;
$n =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$COOK{$n} = $value;
}
# Есть какие-то данные, сверяем их, если пользователь не авторизуется
if ($COOK{login} ne \'\' && $COOK{sess} ne \'\' && $act ne "login")
{
$login="$COOK{login}";
$sess="$COOK{sess}";
&sess;
}
# Пользователь не авторизован вообще и не авторизуется в данный момент
if (($COOK{login} eq \'\' || $COOK{sess} eq \'\') && $act ne "login")
{
&form_login;
exit;
}
# Пользователь авторизуется
if ($act eq "login")
{
&login;
$act="";
}
}
sub login
{
$sth = $dbh->prepare("select id,status from $users_table WHERE login = \'$login\' and pass = \'$pass\'");
$sth->execute || die $dbh->errstr;
@rez=$sth->fetchrow;
### Логин или пароль не верны!
$stat="$rez[1]";
if ($stat eq \'\')
{
print "Content-type:text/html\\n\\n";
&form_login;
exit;
}
# Пользователь авторизован
if ($stat ne \'\')
{
&wr_cookes;
}
}
### Генерируем и пишем данные пользователя в куки и заносим их в базу
sub wr_cookes
{
$sess=rand(32);
print "Set-Cookie: login=$login; expires=now;\\n";
print "Set-Cookie: sess=$sess; expires=now;\\n";
$sth = $dbh->prepare("update $users_table set sess=\'$sess\' where login=\'$login\'");
$sth->execute || die $dbh->errstr;
$sth->finish;
}
sub sess
{
$sth = $dbh->prepare("select id,status,sess from $users_table WHERE login = \'$login\' and sess = \'$sess\'");
$sth->execute || die $dbh->errstr;
@rez=$sth->fetchrow;
$stat="$rez[1]";
### Логин или пароль не верны!
if ($stat eq \'\')
{
&form_login;
exit;
}
# Пользователь авторизован
if ($stat ne \'\')
{
&wr_cookes;
}
}
Далее идет код скрипта, которому передается переменная $stat - статус пользователя.
Еще меня интересует скорость отработки...
И еще. Как мне поставить куки на 20 минут с текущего положения? Хочу сесси сделать. Плюс, как сделаь так, что бы они будуи доступны со всего доменного имени, а не только с текущего скрипта. Заренее спасибо.
-
куки на 20 минут с текущего положения
print "Set-Cookie: login=$login; expires=+20m;\\n";
как сделаь так, что бы они будуи доступны со всего доменного имени, а не только с текущего скрипта
непонятен вопрос
-
непонятен вопрос
-domain => \'.capricorn.com\',
-path => \'/cgi-bin/database\'
perldoc CGI::Cookie
-
А насчет самого метода авторизации, что скажите? Нужно ли динамически каждый раз генерировать $sess, может отрывать ее на одим сеанс и все, без перезаписи при каждом обращении?
непонятен вопрос
Я имел ввиду - при моем методе записи кукей, как я полагаю, ставится разрешение на чтение их только с текущего скрипта. А если на одном доменном имени отрабатывают несколько скриптов, которые используют эту авторизацию (в моем случае - чат, форум, гостевая, внутренняя почта, администрирование...). Нужно, что бы для них чтение этих кукей было разрешенно...
Для этого достаточно написать:
print "Set-Cookie: login=$login; expires=+20m; path=/; domain=$ENV{\'HTTP_HOST\'};\\n";
???
Заранее спасибо.
-
IMHO cookie ставятся только для текущего доменного имени, исключение зделано для *.mydomain.ru и возможно выше
cookie поставить можно с любого места (см. выше) а получить только для текущего
т.е. скрипты с /cgi-bin/s1/ не смогут получить с /cgi-bin/s2/ или / но это IMHO
-
Alone, да ну... Должно же быть разрешенно получать со всего доменного имени? Вспомним тот же PHP-Nuke, куча скриптов, на одной системе авторизации - кукях и все их получают...
-
NeoNox вопрос вроде понял и на него ответил, причем довольно развернуто.
-
У нас подсоляркой perldoc не установлен.
-
http://www.perldoc.com
http://www.google.com -> perldoc CGI::Cookie
-
Для этого достаточно написать?
Да достаточно. Главное, что-бы другие скрипты "понимали" эти куки.
-
Они поймут. Этот модуль используют все скрипты.
Кастати, по самому алгоритму авторизациии что скажите? Ошибки, дыры, ...?
-
Я бы посоветовал использовать Apache::Session вместо rand(32);
http://www.perldoc.com/cpan/Apache/Session.html
Неплохо бы было рассмотреть режим сессий при отключеных куках
А так на первый взгляд все Ок!
-
NeoNox, режим сессия расмотреть было бы не плохо, но первое и единственное, что мне приходит в голову - это проверка по ip, однако усли учесть то, что есть такие вещи, как прокси, корорые скрывают реальный ip, то в итоге получается не хорошо. Да и поломать будет просто, если проще.
Базовая авторизация тоже не подходит - в файле хасвор будет слишком много записей. По записи на кождого пользователя. Вот если бы вместо его можно было прикрутить базу...
За ссылку спасибо - с удовольствием сейчас почитаю.
-
Если я не ошибаюсь, то исходный скрипт можно взломать.
Поясняю:
Допустим, я знаю, что в системе зарегистрирован пользователь Vasya. Я запускаю локальный сервер, устанавливаю в браузере для нужного сайта следующие Cookies:
login=Vasya\' OR (login=\'lalala
sess=\') OR login=\'lalala
Далее я выключаю локальный сервер и захожу на реальный.
В результате запустится функция sess(), которая выполнит следующий запрос:
select id,status,sess from TABLE_NAME WHERE login = \'Vasya\' OR (login=\'lalala\' and sess = \'\') OR login=\'lalala\'
В результате скрипт признает меня Васей, хотя я на самом деле не Вася. Вот так то.
Решения:
1) Нужно проверять все значения, полученные от пользователя, в том числе Cookies. Если известно, что имя состоит из букв, цифр и \'_\', а номер сессии - только из цифр, то следует добавить:
$login=~s/\\W//g;
$sess=~s/\\D//g;
2) Вместо $sth = $dbh->prepare("select id,status,sess from $users_table WHERE login = \'$login\' and sess = \'$sess\'");
$sth->execute || die $dbh->errstr;
используй $sth = $dbh->prepare("select id,status,sess from $users_table WHERE login = ? and sess = ?");
$sth->execute($login, $sess) || die $dbh->errstr;
Поможет даже без пункта 1
3) Думай как хакер. Врага нужно знать.
2ALL: Есть повод задуматься над собственными скриптами.
-
Vladn
И как же ты собираешься устанавливать "в браузере для нужного сайта следующие Cookies"?
-
И как же ты собираешься устанавливать "в браузере для нужного сайта следующие Cookies"?
Элементарно. Допустим, исходный сайт try2hack.ru
1) Добавляю в файл hosts строчку "127.0.0.1 try2hack.ru"
2) Устанавливаю на моем компе апач с перлом, в httpd.conf добавляю
...
3) В папку cgi-bin, указанную в virtualhost, добавляю скрипт a.cgi
#!/usr/bin/perl
print "Content-type: text/html\\n";
print "Set-Cookie:";
....
print "\\n";
print "Done. Poor Vasya";
(p.s. без последней строчки ничего не заработает :)
4) Запускаю апач и запускаю в браузере указанный скрипт. Браузер не закрываю.
5) Останавливаю апач.
6) Удаляю из файла hosts добавленную строчку.
7) Подключаюсь к интернету.
8) Захожу в этом же браузере на страницу авторизации.
9) Беру телефонную трубку и говорю "I\'m in". (Как ни странно, но без этого тоже ничего на заработает).
[off]Информация предоставлена в ознакомительных целях. Практическое применение преследуется законом.[/off]
-
Все правильно. Кроме всего прочего есть тулзы для записи/изменения кук в броузере. Но как ни странно есть алгоритмы которые не позволяют злоумышленникам использовать перезаписаные куки напрямую.
Поиск по форуму даст пищу для осмысления этого.
-
NeoNox
И какие же алгоритмы помешают применить злоумышленнику описанную мною схему? Дайте ссылку, а то я не знаю, что вводить в поисковой фразе (на фразу "алгоритмы куки напрямую" найдена только текущая тема)
-
Vladn:
Вот если бы вместо его можно было прикрутить базу...
mod_mysql_auth
если не ошибаюсь
-
metton:
И как же ты собираешься устанавливать "в браузере для нужного сайта следующие Cookies"?
а почему именно "в браузер". Любой, кто знаком с протоколом HTTP, сможет написать программу/скрипт, которая будет слать куки, которые захочешь и вообще создавать любые ХТТП-запросы.
Вобщем-то Vladn, описал как дыру закрыть:
Vladn:
используй
$sth = $dbh->prepare("select id,status,sess from $users_table WHERE login = ? and sess = ?");
$sth->execute($login, $sess) || die $dbh->errstr;
-
Vladn более чем год назад в этой теме я ответил ссылкой (битой уже, кстати) на Apache::Session. И ответ на вопрос что лучше куры или петухи как ни странно получаем гусей.
Дело в том, что сессии и предназначены для идентификации пользователя без проверок паролей, логинов и прочей секурной информации.
Vladn:
на фразу "алгоритмы куки напрямую" найдена только текущая тема
ты хоть сам-то понял что ты искал?
-
ах я понял что тебя смущает... ну ставить $sth->quote() на введенные пользователем данные всегда полезно. точно так же как и полезно проверять ответ сервера.
-
точно так же как и полезно проверять ответ сервера
Хм... Что за ответ? Ответ на что?
-
metton ты из какой сказки?
metton:
Что за ответ? Ответ на что?
ответ на запрос. проверка на ответ сервера об ошибке.
-
NeoNox
Я просто не понял, к чему ты это сказал. Вроде говорили про уязвимость в запросе к БД.