информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetЗа кого нас держат?Сетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 С наступающим 
 Microsoft обещает радикально усилить... 
 Ядро Linux избавляется от российских... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Пасиб, работаю, к вечеру будут результаты. 14.07.04 09:14  Число просмотров: 1538
Автор: !? <!?> Статус: Member
<"чистая" ссылка>
Сразу выражу благодарность за помощь: Спасибо.

> Буду излагать по-порядку. Вначале про то, как Ты все эти
> данные хранишь.
Я чувствую (всё ещё не прочитал), что намеченная ревизия этого модуля будет проходить долго и кропотливо %).

> Разобрался я наконец что у тебя к чему и мне это не
> понравилось. Получается, что у тебя на каждого юзера
> имеется по два файла - .auth и .hash. Зачем? Я бы зделал
> вообще один файл, в котором подряд было бы записано то, что
> ты хранишь в .hash. А id - это номер записи. Данные, вроде
> как, все фиксированной длинны - логин, пароль, хэш,
> контрольное число, дата, время. Если, конечно, ты не
> хранишь дополнительно личных сообщений, "о себе" и
> подобного. Если хранишь - то можно делать и с профайлами,
> где имя файла - это логин, а внутри уже вся инфа, включая
> id. Хотя особой нужды я в id не вижу (а если и надо, то
> можно создать дополнительный файл, где будет указано
> сопоставление id к логинам юзерей, которые сидят в данный
> момент). В общем, это уже совсем отдельная тема (а топик
> текстовики vs. БД имхо рано закрыли)
Храню в разных файлах, тк hash-файлы содержат пароль, уровень доступа (УД), контрольное число (КЧ), и контрольное время/дату (КВД), т.е. важные данные, при потере которых будут проблемы. А в auth-файле хранится всего лишь краткая инфа: логин, дата регистрации и статус.

> sAuth1 впринципе нормальная, вот только $uID непонятно
> откуда вылезает - это просто ты не досмотрел. $uID
> определяется либо в sGetID, либо если присвоить ей левую
> часть хэша, чего тоже не делается. Ну и непонятно зачем
> тебе нужна переменная $gPAUSE. С $gPAGE тоже не совсем ясно
> (в приведённом коде её использование слабо отражено) - но
> это уже неважные мелочи.
На $gPAGE не стоит обращать внимания, это идентификатор типа просматриваемой страницы, здесь он не играет большой роли, тк в любом случае происходит аутентификация.
$gPAUSE.. сегодня сяду переписывать и от многого избавлюсь. Код выложу,- сравнить можно будет %).

> sOff я бы писал по-другому. Ты чего-то слишком замудрил.
> Проще было бы просто прописывать в .hash-файл новое время
> последнего обращения, превышающего по таймауту $cFSession,
> а после выводить сообщение типа "ошибка авторизации" или
> "вы удачно вышли" (добавить ещё одно условие несложное) и в
> конце вызывать exit().
Ну дык для выхода тоже нужно пройти процедуру аутентификации, иначе все начнут друг друга «выходить» %). Или я непрально понял?

> Что касается времени, то тут я даже не пытался разбираться
> - с детства проблемы были с арифметикой, но вроде как ты
> учитываешь только день и число секунд после полуночи (вроде
> как судя по аргументам, но опять же я не пытался
> разобраться). Я бы вообще localtime не вызывал, а
> использовал бы (time/60-n) (n - количество минут,
> проходящих лет за десять - что бы число было поменьше). А
> ещё лучше применить побитовый сдвиг, но это уже моя личная
> параноя (люблю всё оптимизировать :-)).
У меня идёт учёт минут дня и номера дня/месяца. Оптимизировать, конечно, не помешало бы.. Подумаю над этим.

> Теперь поговорим непосредственно о безопастности. Если
> такую аутентификацию применять в форуме/чате/гостевой
> книге, то есть все шансы, что злоумышленник :-) сможет
> впихнуть на страницу вызов внешнего CGI-скрипта и прочитать
> твою адресную строку. А заодно инфу о браузере и IP. Таким
> образом хэш уже известен, инфу о браузере можно подделать,
> а в случае использования клиентом анонимного прокси, ещё и
> айпишник. Хотя вроде как я наслышан, что IP подделывают,
> что-то там подправляя в каких-то пакетах, но это уже не моя
> область.
Подделка IP,- вещь несложная.
Но хАкИр не знает по какому принципу формируется хеш, не знает ничего о контрольном числе, хотя это и можно обойти, но от такого тех.уровня хАкИра никто не застрахован %).

> Что бы этого избежать можно либо применять кукисы, либо
> метод POST отправки формы. Тогда ссылка будет выглядеть как
> <a href="javascript:xxx(hash,url)">. Сам скрипт:
>
> <script language=javascript>
> function xxx(hash,url) {
> document.f1.action=url;
> //не помню точно, как записывается
> //action надо будет доки почитать
> document.f1.h1.value=hash;
> document.f1.submit();
> }
> </script>
>
> Ну и должна присутствовать форма:
>
> <form name=f1 method=post>
> <input type=hidden name=hash>
> </form>
>
> Это, конечно, уже извращения, однако работает и вполне
> надёжно. (я так всё подробно излагаю, потому что хочу
> статью потом из этого замуть) Кстати в случае применения
> кукисов, можно вообще таймаут не использовать - время их
> жизни может достаточно жёстко задаваться, однако я бы на
> это полагаться не стал.
Не.. куки я использовать не буду %).
А про яву.. блин.. как мне надоели эти прибамбасы ;(.. Подумаю..

> Но это всё больше ребячество. Теперь про действительно
> серьёзную и уже ошибку. Посмотри на функцию аутентификации:
> она НЕ ПРОВЕРЯЕТ КОНТРОЛЬНОЕ ЧИСЛО!! Она его использует
> только для генерации хеша, причём само контрольное число
> высчитывается заново в начале аутентификации. Дальше
> вызывается crypt($all,$rnd) (не помню как переменная со
> случайным числом называется) и сравнивает результат с
> переданным пользователем хешем. Зная алгоритм
> аутентификации (а предполагается, что я его знаю), я могу
> посчитать контрольное число для себя (используя СВОЙ IP,
> ведь число пересчитывается до проверки!!). Функцию crypt я
> тоже знаю - она по твоим словам из стандартной библиотеки к
> тому же. Дальше я пишу простой эксплоит, который используя
> МОЁ контрольное число перебирает все подряд значения $rnd
> (их всего 99 - перебор займёт две минуты на модеме с плохой
> связью), шифрует их известной функцией crypt и открывает
> страницу, отправляя полученный хеш. В одном из 99
> вариантов, мой хеш подойдёт. Защиты от брутфорса твоя
> функция аутентификации не имеет - перебрать все значения
> мне никто не помешает. Даже если случайное число будет
> выбираться из более крупного диапазона, перебор займёт не
> так уж много времени.
Нифига %). Функция sHASH как раз для предотвращения этого и написана %).
А строку $gRND= int(rand(99)); я просто забыл переместить в модуль авторизации, при аутентификации КЧ загружается из hash-файла.

> Исправить ошибку можно отменив пересчёт контрольного числа
> заново, но это не спасёт ситуацию - IP можно подделать, а
> проверка HTTP_USER_AGENT далеко не каждого остановит.
> Следует как минимум защититься от перебора.
>
> А вообще наличие криптографии в данном случае себя имхо не
> оправдывает - хеш можно делать вообще СЛУЧАЙНЫМ числом - от
> этого никто не пострадает, только процессор разгрузится, а
> контрольное число проверять независимо. Хотя наличие
> контрольного числа в таком виде как оно есть уже являет из
> себя серьёзную угрозу. Я, допустим, не умею подделывать IP,
> но умею подделывать HTTP_USER_AGENT. Контрольное число -
> это сумма ASCII-значений символов в трёх переменных
> окружения. Причем основной вес ему придаёт именно тот самый
> HTTP_USER_AGENT. Подделав его, я могу даже без подделки IP
> добиться нужного мне контрольного числа.
>
> Вывод: делай защиту от перебора (как только передаётся
> ошибочный хеш - руби сессию), не надо каждый раз
> пересчитывать контрольное число - пользуй то, которое
> получил при авторизации, IP проверяй независимо от
> контрольного числа (в том числе и проксю). Желательно
> конечно ещё передавать хеш не через адресную строку - но
> это достаточно муторно. Идеальный вариант - хеш после
> каждой аутентификации менять, но тогда пользователи
> потеряют функцию "открыть в новом окне", что не хорошо.
>
> Фуф.. вроде всё... Вот такое вот исследование безопастности
> %)
Круто ;).
Сёня вечером перечитаю и переработаю всё %).

> ЗЫ. Однако если кто-то вклинится в траффик, такая защита
> становится уже не актуальной.
Ну от этого мало кто защищён %).

> ЗЗЫ. А чего за crypt? Хотя бы в какой библиотеке?
В стандартной, в той, в которой вся математика, видимо.. Я не смотрел ещё.
<programming>
[Perl] Насколько дырява моя система аутентификации? %) 11.07.04 21:08  
Автор: !? <!?> Статус: Member
Отредактировано 12.07.04 04:56  Количество правок: 1
<"чистая" ссылка>
Это мой модуль аутентификации, может есть люди, имеющие возможность проверить его на «защищённость»?.. Буду премногоблагодарен %).

Ключевые переменные- $uID (ID юзера) и @sA[1] (уровень допуска)..
Опасный уровень допуска нарушителя- менее 8
ID гостя- <>
Разрешение на проявление активности- $cUA eq 1 (при нуле активность блокируется)

вот..


#!/usr/bin/perl

sub sGetID
{
$sGI= 0;
while (open $sGID, "conf/auth/".$sGI.".auth")
{
$sGID0= <$sGID>;
close $sGID;
@sGID= split(/•/, $sGID0);
$uID= $sGI if @sGID[0] eq $sLOGIN;
$sGI++;
}
$uID= "<>" if int($uID) ne $uID;
}

sub sHASH
{
($t0, $t1, $t2, $t3, $t4) = localtime(time - (3600* $cFGMT));
$gTIME= $t2* 3600+ $t1* 60+ $t0;
$gDAY= $t3.":".$t4;
@envs= ($ENV{"REMOTE_ADDR"}, $ENV{"HTTP_USER_AGENT"}, $ENV{"HTTP_X_FORWARDED_FOR"});
$all= 0;
foreach $envs (@envs)
{
@count= split(//, $envs);
foreach $count (@count)
{
$all+= ord($count);
}
}
$gRND= int(rand(99));
}

sub sHASH0
{
if (open $sU, ">conf/auth/hash/".$uID.".hash")
{
print $sU @sA[0]."•".@sA[1]."•".$gRND."\n".$gTIME."•".$gDAY;
close $sU;
}
$uHASH= $uID.":".substr(crypt($all, $gRND), 2, 8);
}

sub sAuth0
{
$sLOGIN= $params->param("login");
$sPW= $params->param("pass");
$sLOGIN=~s/\r|\n|\\|\/|\|/g;

if ($sLOGIN and $sPW)
{
&sGetID;
if (open $sA0, "conf/auth/hash/".$uID.".hash")
{
$sA1= <$sA0>;
close $sA0;
@sA= split(/•/, $sA1);
if (@sA[0] eq crypt($sPW, $sPW))
{
$cUA= 1;
sHASH;
sHASH0;
} else
{
$uID= "<>";
$cUA= 0;
}
}
} else
{
$uID= "<>";
}
}

sub sAuth1
{
$uID= "<>" if int($uID) ne $uID;
$uHASH= $params->param("hash");
@uHASH= split(/:/, $uHASH);
sHASH;
if (open $sA0, "conf/auth/hash/".@uHASH[0].".hash")
{
@sA1= <$sA0>;
close $sA0;
@sA1[0]=~ s/\r|\n//g;
@sA1[1]=~ s/\r|\n//g;
@sA0= split(/•/, @sA1[0]);
@sA1= split(/•/, @sA1[1]);
}
if ((@uHASH[1] eq substr(crypt($all, @sA0[2]), 2, 8)) and ($gDAY eq @sA1[1]))
{
if (($gTIME- @sA1[0])> $cFSession)
{
print "Ваша сессия устарела, авторизуйтесь заново.";
$uID= "<>";
$gPAUSE= ($gTIME- @sA1[0]);
$gPAGE= "";
$cUA= 0;
} else
{
$uID= @uHASH[0];
if (open $sU, ">conf/auth/hash/".$uID.".hash")
{
print $sU @sA0[0]."•".@sA0[1]."•".@sA0[2]."\n".$gTIME."•".$gDAY;
close $sU;
$cUA= 1;
} else
{
print "При учёте сессии произошла ошибка, попробуйте авторизоваться заново.";
$uID= "<>";
}
}
}
}

sub sOff
{
open $xPO, "conf/auth/hash/".$uID.".hash";
@xTS= <$xPO>;
close $xPO;
@xPO= split(/•/, @xTS[0]);
open $xPO, ">conf/auth/hash/".$uID.".hash";
print $xPO @xPO[0]."•".@xPO[1];
close $xPO;
$uID= "<>";
$uHASH= "";
}

&sAuth0 if $gPAGE eq "auth";
&sAuth1 if $gPAGE ne "auth";
&sOff if $gPAGE eq "off";
$gPAGE= "" if $gPAGE eq "off";

if ($uID ne "<>")
{
if (open $sA0, "conf/auth/hash/".$uID.".hash")
{
$sA1= <$sA0>;
close $sA0;
@sA= split(/•/, $sA1);
} else
{
@sA[1]= 10;
}
} else
{
@sA[1]= 10;
}

return true;
Спасибо за помощь всем, кто успел помочь, терь прошу... 14.07.04 19:04  
Автор: !? <!?> Статус: Member
Отредактировано 14.07.04 19:10  Количество правок: 2
<"чистая" ссылка>
Спасибо за помощь всем, кто успел помочь, терь прошу проверить результаты проделанной работы:
Как смог закомментил..

#!/usr/bin/perl sub sGetID #определение ID по логину {  open $sTEMP, "conf/auth/idlist"; #список вида ID•LOGIN  @sTEMP= <$sTEMP>;  close $sTEMP;  foreach $sTEMP (@sTEMP)  {   $sTEMP=~ s/\r|\n//g;   @sTEMP0= split(/•/, $sTEMP);   if (@sTEMP0[1] eq $_[0]) {return int(@sTEMP0[0]); last;}  } } sub sHASH #вычисление «хеша бравзера» и контрольного числа (при аутентификации КЧ загружается из hash-файлв) {  @sENV= ($ENV{"REMOTE_ADDR"}, $ENV{"HTTP_USER_AGENT"}, $ENV{"HTTP_X_FORWARDED_FOR"});  foreach $sENV (@sENV)  {   foreach ((split(//, $sENV))) {$sHASH0+= ord(($_));};  }  $sRND= int(rand(99)); } sub sHASH0 #сохранение параметров при аутентификации {  if (open $sTEMP, ">conf/auth/hash/".$uID.".hash")  {   print $sTEMP @sA[0]."\n".$sRND."•".$gTIME; #сохранение текущего статуса   close $sTEMP;  }  $uHASH= $uID.":".substr(crypt($sHASH0, $sRND), 2, 8); #хеш для линкования страницы } sub sAuth0 {  $gPAGE= ""; #при авторизации переход на главную  if ($sPW)  {   $uID= sGetID ($sLOGIN);   if (open $sA0, "conf/auth/hash/".$uID.".hash")   {    @sA= <$sA0>;    close $sA0;    grep {$_=~ s/\r|\n//g;} (@sA); #обрезка знаков конца строки    if (@sA[0] eq crypt($sPW, $sPW))    {     sHASH; #подготовка хеша     sHASH0; #запись хеша     print "Вы успешно авторизовались";    } else    {     $uID= "";     print "Пароль неверен";    }   } else   {    $uID= "";    print "Аккаунт не зарегистрирован";   }  } else  {   $uID= "";   print "Пароль не введён";  } } sub sOff #функция логоффа {  open $xTEMP, "conf/auth/hash/".$uID.".hash";  @xTEMP= <$xTEMP>;  close $xTEMP;  open $xTEMP, ">conf/auth/hash/".$uID.".hash";  print $xTEMP @xTEMP[0];  close $xTEMP;  $uID= "";  $gPAGE= ""; #возврат на заглавную страницу  print "Вы успешно вышли"; } sub sAuth1 {  @uHASH= split(/:/, $uHASH); #приём хеша  @uHASH[0]= "" if @uHASH[0] ne int(@uHASH[0]);  $uID= @uHASH[0];  sHASH;  if ($uID ne "")  {   open $sTEMP, "conf/auth/hash/".$uID.".hash";   @sTEMP= <$sTEMP>;   close $sTEMP;   @sTEMP[1]=~ s/\r|\n//g;   @sTEMP0= split(/•/, @sTEMP[1]);   $sRND= @sTEMP0[0];   #проверка хеша и сессии   if ((@uHASH[1] eq substr(crypt($sHASH0, $sRND), 2, 8)) and (($gTIME- @sTEMP0[1])< $cFSession))   {    open $sTEMP, ">conf/auth/hash/".$uID.".hash";    #при положиельном результате проверки,- обновление данных сессии    print $sTEMP @sTEMP[0].$sRND."•".$gTIME;    close $sTEMP;   } else   {    print "Невозможно аутентифицироваться";    $uID= "";   }  } } sub sVars {  #очистка, в том числе от хАкИраФФ %)  $sTEMP= ""; @sTEMP= ""; $sTEMP0= ""; @sTEMP0= "";  $sENV= ""; @sENV= ""; $gRND= ""; $sHASH0= ""; @sA= ""; @sA0= "";  if ($uID ne "")  {   open $xTEMP, "conf/auth/".$uID.".auth";   @uINFO= split(/•/, <$xTEMP>);   close $xTEMP;   @uINFO[3]=~ s/\r|\n//g;   @uINFO[3]= 10 if $uINFO[3] ne int(@uINFO[3]);   $cUA= 1;  } else  {   $uHASH= "";   $cUA= 0;  } } #приём входных параметров $gTIME= (time- ($cFGMT* 3600)); $sLOGIN= $params->param("login"); $sPW= $params->param("pass"); $uHASH= $params->param("hash"); $cUA= 0; #по умолчанию блокировать активность &sAuth1 if not $sLOGIN; &sAuth0 if $sLOGIN; #если человек вводит логин, то он хочет авторизоваться, по идее.. %) &sOff if $gPAGE eq "off"; &sVars; return true;
Ты бы код как-нибудь закамментил.. 12.07.04 16:03  
Автор: Heller <Heller> Статус: Elderman
<"чистая" ссылка>
Честно скажу - читать невозможно. К тому же код, как я понял, не полностью приведён. Ещё не понятно почему ты к элементам массива обращаешься, используя префикс @...
Вобщем, откамменти хоть как-нибудь - там уже буду копать. Лучше просто приведи краткое описание переменных и функций..
ну как бы.. если вчитываться.. %) 12.07.04 16:21  
Автор: !? <!?> Статус: Member
<"чистая" ссылка>
> Честно скажу - читать невозможно. К тому же код, как я
> понял, не полностью приведён. Ещё не понятно почему ты к
> элементам массива обращаешься, используя префикс @...
> Вобщем, откамменти хоть как-нибудь - там уже буду копать.
> Лучше просто приведи краткое описание переменных и
> функций..

ну.. основные я написал,- остальное:

#!/usr/bin/perl

sub sGetID #функция определения ID пользователя по его логину
{
$sGI= 0;
while (open $sGID, "conf/auth/".$sGI.".auth")
{
$sGID0= <$sGID>;
close $sGID;
@sGID= split(/•/, $sGID0);
$uID= $sGI if @sGID[0] eq $sLOGIN;
$sGI++;
}
$uID= "<>" if int($uID) ne $uID;
}

sub sHASH #подготовка хеша для данного пользователя
{
($t0, $t1, $t2, $t3, $t4) = localtime(time - (3600* $cFGMT));
$gTIME= $t2* 3600+ $t1* 60+ $t0;
$gDAY= $t3.":".$t4;
@envs= ($ENV{"REMOTE_ADDR"}, $ENV{"HTTP_USER_AGENT"}, $ENV{"HTTP_X_FORWARDED_FOR"});
$all= 0;
foreach $envs (@envs)
{
@count= split(//, $envs);
foreach $count (@count)
{
$all+= ord($count);
}
}
$gRND= int(rand(99));
}

sub sHASH0 #запись контрольного числа (при авторизации)
{
if (open $sU, ">conf/auth/hash/".$uID.".hash")
{
print $sU @sA[0]."•".@sA[1]."•".$gRND."\n".$gTIME."•".$gDAY;
close $sU;
}
$uHASH= $uID.":".substr(crypt($all, $gRND), 2, 8);
}

sub sAuth0 #проверка пароля
{
$sLOGIN= $params->param("login");
$sPW= $params->param("pass");
$sLOGIN=~s/\r|\n|\\|\/|\|/g;

if ($sLOGIN and $sPW)
{
&sGetID;
if (open $sA0, "conf/auth/hash/".$uID.".hash") #открытие файла паролей
{
$sA1= <$sA0>;
close $sA0;
@sA= split(/•/, $sA1); #он имеет формат PASS•AccessLevel•ControlN
if (@sA[0] eq crypt($sPW, $sPW))
{
$cUA= 1; #разрешение на активность
sHASH;
sHASH0;
} else
{
$uID= "<>"; #а так у нас посылают %)
$cUA= 0;
}
}
} else
{
$uID= "<>";
}
}

sub sAuth1 #аутентификация
{
$uID= "<>" if int($uID) ne $uID; #обман рубится на корню %)
$uHASH= $params->param("hash");
@uHASH= split(/:/, $uHASH);
sHASH;
if (open $sA0, "conf/auth/hash/".@uHASH[0].".hash")
{
@sA1= <$sA0>;
close $sA0;
@sA1[0]=~ s/\r|\n//g;
@sA1[1]=~ s/\r|\n//g;
@sA0= split(/•/, @sA1[0]);
@sA1= split(/•/, @sA1[1]);
}
if ((@uHASH[1] eq substr(crypt($all, @sA0[2]), 2, 8)) and ($gDAY eq @sA1[1]))
{
if (($gTIME- @sA1[0])> $cFSession)
{
print "Ваша сессия устарела, авторизуйтесь заново.";
$uID= "<>";
$gPAUSE= ($gTIME- @sA1[0]);
$gPAGE= "";
$cUA= 0;
} else
{
$uID= @uHASH[0];
if (open $sU, ">conf/auth/hash/".$uID.".hash")
{
print $sU @sA0[0]."•".@sA0[1]."•".@sA0[2]."\n".$gTIME."•".$gDAY;
close $sU;
$cUA= 1;
} else
{
print "При учёте сессии произошла ошибка, попробуйте авторизоваться заново.";
$uID= "<>";
}
}
}
}

sub sOff
{
open $xPO, "conf/auth/hash/".$uID.".hash";
@xTS= <$xPO>;
close $xPO;
@xPO= split(/•/, @xTS[0]);
open $xPO, ">conf/auth/hash/".$uID.".hash";
print $xPO @xPO[0]."•".@xPO[1];
close $xPO;
$uID= "<>";
$uHASH= "";
}

&sAuth0 if $gPAGE eq "auth";
&sAuth1 if $gPAGE ne "auth";
&sOff if $gPAGE eq "off";
$gPAGE= "" if $gPAGE eq "off";

if ($uID ne "<>")
{
if (open $sA0, "conf/auth/hash/".$uID.".hash")
{
$sA1= <$sA0>;
close $sA0;
@sA= split(/•/, $sA1);
} else
{
@sA[1]= 10;
}
} else
{
@sA[1]= 10;
}

return true;

а вообще, имхо, тут и так всё ясно..
если уж чё конкретное,- то и спросить можно %)
Посмотрел пока не до конца - дошёл только до функции sAuth1... 13.07.04 16:42  
Автор: Heller <Heller> Статус: Elderman
<"чистая" ссылка>
Посмотрел пока не до конца - дошёл только до функции sAuth1 и пока остановился - ночью буду смотреть дальше.
А пока никаких ошибок в безопастности вроде бы нет, но имеются непонятные моменты в самом коде.

Во-первых, в sGetID можно было бы вместо
$uID= $sGI if @sGID[0] eq $sLOGIN
использовать
if (@sGID[0] eq $sLOGIN) {$uID= $sGI; break}
Нафига нужны лишние итерации? Да и вообще я бы организовывал базу по другому - все поля у тебя фиксированной длинны, так почему бы не создать только один .auth-файл? А потом обращаться к конкретным записям с помощью seek.

Второй момент: зачем ты хэш обрезаешь substr'ом? Почему не полностью приводишь? Вроде стойкость от этого падает. Хотя может быть я просто код не доконца изучил и чего-то пока не понимаю %)

Третее: что за функция crypt? Насколько ей доверять можно? Просто даже если сама функция вполне надёжна, у меня дольшие сомнения, что результат вычисления crypt($sPW, $sPW) будет так уж сложно предсказать.. Ты бы что ли функцию приыёл - или хотя бы в общих чертах рассказал.

Четвёртое: функция sAuth0 берёт пароль из файла $uID.hash, который по-идее на момент запуска sAuth0 ещё не существует! Он у Тебя создаётся функцией sHASH0, которая вызывается уже из sAuth0 (насколько я понимаю, она вызывается первой). Опять же то ли я чего не понял, то ли глюк.

Ну ищё куча замечаний по мелочам, типа зачем та же sAuth0 выполняет $uID="<>" (тот что последний) - ведь это в любом случае раньше делает sGetID.. Много недочётов короче. Завтра рапортую об исследовании остальной части кода :-)


> а вообще, имхо, тут и так всё ясно..

Да не ясно.. Это кто как привык кодить.. У меня, например, кругом одни только регулярные выражения.. У тебя int, substr.. Просто не привычно. Да и по мелочам - ты хэндлеры обозначаешь как $handler, а я привык как HANDLER - тоже сбивает с толку :-) Perl -такой язык..

ЗЫ. И всё-таки.. Почему @mass[i], а не $mass[i]?
7 пасиб %) 13.07.04 17:08  
Автор: !? <!?> Статус: Member
<"чистая" ссылка>
> Посмотрел пока не до конца - дошёл только до функции sAuth1
> и пока остановился - ночью буду смотреть дальше.
> А пока никаких ошибок в безопастности вроде бы нет, но
> имеются непонятные моменты в самом коде.
>
> Во-первых, в sGetID можно было бы вместо
> $uID= $sGI if @sGID[0] eq $sLOGIN
> использовать
> if (@sGID[0] eq $sLOGIN) {$uID= $sGI; break}
Учту, пасиб.

> Нафига нужны лишние итерации? Да и вообще я бы
> организовывал базу по другому - все поля у тебя
> фиксированной длинны, так почему бы не создать только один
> .auth-файл? А потом обращаться к конкретным записям с
> помощью seek.
Опасно, тк при каждой новой сессии файл с паролем изменяется..
Хотя, над этим можно подумать.. Например, пароли хранить в одном файле, а данные сессии уже для каждого в своём.
Но чёт тупо получается, выгоды в таком варианте уже не вижу %).

> Второй момент: зачем ты хэш обрезаешь substr'ом? Почему не
> полностью приводишь? Вроде стойкость от этого падает. Хотя
> может быть я просто код не доконца изучил и чего-то пока не
> понимаю %)
Первые два символа,- чисто техническая проблема: результат работы crypt(11111, 22222), например, равен 22iBgJ8VPh9Ak, т.е. первые два символа меня смущают ;). А последние.. Да так, чтоб выглядело красивше %).

> Третее: что за функция crypt? Насколько ей доверять можно?
> Просто даже если сама функция вполне надёжна, у меня
> дольшие сомнения, что результат вычисления crypt($sPW,
> $sPW) будет так уж сложно предсказать..
Функция библиотечная, нашёл методом тыка и описания никогда не видел ;). Надо какнть глянуть..

> Ты бы что ли
> функцию приыёл - или хотя бы в общих чертах рассказал.

> Четвёртое: функция sAuth0 берёт пароль из файла $uID.hash,
> который по-идее на момент запуска sAuth0 ещё не существует!
> Он у Тебя создаётся функцией sHASH0, которая вызывается уже
> из sAuth0 (насколько я понимаю, она вызывается первой).
> Опять же то ли я чего не понял, то ли глюк.
Тут ты не понял,- $uID.hash существует с момента регистрации аккаунта, в нём хранится хеш его пароля, с которым как раз сравнивается хеш заданного пользователем пароля.

> Ну ищё куча замечаний по мелочам, типа зачем та же sAuth0
> выполняет $uID="<>" (тот что последний) - ведь это в
> любом случае раньше делает sGetID.. Много недочётов короче.
> Завтра рапортую об исследовании остальной части кода :-)
Ну пасиб %). Ревизию, чувствуется, проведу конкретную ;).

> > а вообще, имхо, тут и так всё ясно..
>
> Да не ясно.. Это кто как привык кодить.. У меня, например,
> кругом одни только регулярные выражения.. У тебя int,
> substr.. Просто не привычно. Да и по мелочам - ты хэндлеры
> обозначаешь как $handler, а я привык как HANDLER - тоже
> сбивает с толку :-) Perl -такой язык..
Ну да..

> ЗЫ. И всё-таки.. Почему @mass[i], а не
> $mass[i]?
А мне так нравится!! ;) Пёрл - такой язык! %).
Дырявая твоя аутентификация %) 14.07.04 08:10  
Автор: Heller <Heller> Статус: Elderman
<"чистая" ссылка>
Буду излагать по-порядку. Вначале про то, как Ты все эти данные хранишь.

Разобрался я наконец что у тебя к чему и мне это не понравилось. Получается, что у тебя на каждого юзера имеется по два файла - .auth и .hash. Зачем? Я бы зделал вообще один файл, в котором подряд было бы записано то, что ты хранишь в .hash. А id - это номер записи. Данные, вроде как, все фиксированной длинны - логин, пароль, хэш, контрольное число, дата, время. Если, конечно, ты не хранишь дополнительно личных сообщений, "о себе" и подобного. Если хранишь - то можно делать и с профайлами, где имя файла - это логин, а внутри уже вся инфа, включая id. Хотя особой нужды я в id не вижу (а если и надо, то можно создать дополнительный файл, где будет указано сопоставление id к логинам юзерей, которые сидят в данный момент). В общем, это уже совсем отдельная тема (а топик текстовики vs. БД имхо рано закрыли)

sAuth1 впринципе нормальная, вот только $uID непонятно откуда вылезает - это просто ты не досмотрел. $uID определяется либо в sGetID, либо если присвоить ей левую часть хэша, чего тоже не делается. Ну и непонятно зачем тебе нужна переменная $gPAUSE. С $gPAGE тоже не совсем ясно (в приведённом коде её использование слабо отражено) - но это уже неважные мелочи.

sOff я бы писал по-другому. Ты чего-то слишком замудрил. Проще было бы просто прописывать в .hash-файл новое время последнего обращения, превышающего по таймауту $cFSession, а после выводить сообщение типа "ошибка авторизации" или "вы удачно вышли" (добавить ещё одно условие несложное) и в конце вызывать exit().

Что касается времени, то тут я даже не пытался разбираться - с детства проблемы были с арифметикой, но вроде как ты учитываешь только день и число секунд после полуночи (вроде как судя по аргументам, но опять же я не пытался разобраться). Я бы вообще localtime не вызывал, а использовал бы (time/60-n) (n - количество минут, проходящих лет за десять - что бы число было поменьше). А ещё лучше применить побитовый сдвиг, но это уже моя личная параноя (люблю всё оптимизировать :-)).

Теперь поговорим непосредственно о безопастности. Если такую аутентификацию применять в форуме/чате/гостевой книге, то есть все шансы, что злоумышленник :-) сможет впихнуть на страницу вызов внешнего CGI-скрипта и прочитать твою адресную строку. А заодно инфу о браузере и IP. Таким образом хэш уже известен, инфу о браузере можно подделать, а в случае использования клиентом анонимного прокси, ещё и айпишник. Хотя вроде как я наслышан, что IP подделывают, что-то там подправляя в каких-то пакетах, но это уже не моя область.

Что бы этого избежать можно либо применять кукисы, либо метод POST отправки формы. Тогда ссылка будет выглядеть как <a href="javascript:xxx(hash,url)">. Сам скрипт:

<script language=javascript>
function xxx(hash,url) {
document.f1.action=url;
//не помню точно, как записывается
//action надо будет доки почитать
document.f1.h1.value=hash;
document.f1.submit();
}
</script>

Ну и должна присутствовать форма:

<form name=f1 method=post>
<input type=hidden name=hash>
</form>

Это, конечно, уже извращения, однако работает и вполне надёжно. (я так всё подробно излагаю, потому что хочу статью потом из этого замуть) Кстати в случае применения кукисов, можно вообще таймаут не использовать - время их жизни может достаточно жёстко задаваться, однако я бы на это полагаться не стал.

Но это всё больше ребячество. Теперь про действительно серьёзную и уже ошибку. Посмотри на функцию аутентификации: она НЕ ПРОВЕРЯЕТ КОНТРОЛЬНОЕ ЧИСЛО!! Она его использует только для генерации хеша, причём само контрольное число высчитывается заново в начале аутентификации. Дальше вызывается crypt($all,$rnd) (не помню как переменная со случайным числом называется) и сравнивает результат с переданным пользователем хешем. Зная алгоритм аутентификации (а предполагается, что я его знаю), я могу посчитать контрольное число для себя (используя СВОЙ IP, ведь число пересчитывается до проверки!!). Функцию crypt я тоже знаю - она по твоим словам из стандартной библиотеки к тому же. Дальше я пишу простой эксплоит, который используя МОЁ контрольное число перебирает все подряд значения $rnd (их всего 99 - перебор займёт две минуты на модеме с плохой связью), шифрует их известной функцией crypt и открывает страницу, отправляя полученный хеш. В одном из 99 вариантов, мой хеш подойдёт. Защиты от брутфорса твоя функция аутентификации не имеет - перебрать все значения мне никто не помешает. Даже если случайное число будет выбираться из более крупного диапазона, перебор займёт не так уж много времени.

Исправить ошибку можно отменив пересчёт контрольного числа заново, но это не спасёт ситуацию - IP можно подделать, а проверка HTTP_USER_AGENT далеко не каждого остановит. Следует как минимум защититься от перебора.

А вообще наличие криптографии в данном случае себя имхо не оправдывает - хеш можно делать вообще СЛУЧАЙНЫМ числом - от этого никто не пострадает, только процессор разгрузится, а контрольное число проверять независимо. Хотя наличие контрольного числа в таком виде как оно есть уже являет из себя серьёзную угрозу. Я, допустим, не умею подделывать IP, но умею подделывать HTTP_USER_AGENT. Контрольное число - это сумма ASCII-значений символов в трёх переменных окружения. Причем основной вес ему придаёт именно тот самый HTTP_USER_AGENT. Подделав его, я могу даже без подделки IP добиться нужного мне контрольного числа.

Вывод: делай защиту от перебора (как только передаётся ошибочный хеш - руби сессию), не надо каждый раз пересчитывать контрольное число - пользуй то, которое получил при авторизации, IP проверяй независимо от контрольного числа (в том числе и проксю). Желательно конечно ещё передавать хеш не через адресную строку - но это достаточно муторно. Идеальный вариант - хеш после каждой аутентификации менять, но тогда пользователи потеряют функцию "открыть в новом окне", что не хорошо.

Фуф.. вроде всё... Вот такое вот исследование безопастности %)

ЗЫ. Однако если кто-то вклинится в траффик, такая защита становится уже не актуальной.

ЗЗЫ. А чего за crypt? Хотя бы в какой библиотеке?
Пасиб, работаю, к вечеру будут результаты. 14.07.04 09:14  
Автор: !? <!?> Статус: Member
<"чистая" ссылка>
Сразу выражу благодарность за помощь: Спасибо.

> Буду излагать по-порядку. Вначале про то, как Ты все эти
> данные хранишь.
Я чувствую (всё ещё не прочитал), что намеченная ревизия этого модуля будет проходить долго и кропотливо %).

> Разобрался я наконец что у тебя к чему и мне это не
> понравилось. Получается, что у тебя на каждого юзера
> имеется по два файла - .auth и .hash. Зачем? Я бы зделал
> вообще один файл, в котором подряд было бы записано то, что
> ты хранишь в .hash. А id - это номер записи. Данные, вроде
> как, все фиксированной длинны - логин, пароль, хэш,
> контрольное число, дата, время. Если, конечно, ты не
> хранишь дополнительно личных сообщений, "о себе" и
> подобного. Если хранишь - то можно делать и с профайлами,
> где имя файла - это логин, а внутри уже вся инфа, включая
> id. Хотя особой нужды я в id не вижу (а если и надо, то
> можно создать дополнительный файл, где будет указано
> сопоставление id к логинам юзерей, которые сидят в данный
> момент). В общем, это уже совсем отдельная тема (а топик
> текстовики vs. БД имхо рано закрыли)
Храню в разных файлах, тк hash-файлы содержат пароль, уровень доступа (УД), контрольное число (КЧ), и контрольное время/дату (КВД), т.е. важные данные, при потере которых будут проблемы. А в auth-файле хранится всего лишь краткая инфа: логин, дата регистрации и статус.

> sAuth1 впринципе нормальная, вот только $uID непонятно
> откуда вылезает - это просто ты не досмотрел. $uID
> определяется либо в sGetID, либо если присвоить ей левую
> часть хэша, чего тоже не делается. Ну и непонятно зачем
> тебе нужна переменная $gPAUSE. С $gPAGE тоже не совсем ясно
> (в приведённом коде её использование слабо отражено) - но
> это уже неважные мелочи.
На $gPAGE не стоит обращать внимания, это идентификатор типа просматриваемой страницы, здесь он не играет большой роли, тк в любом случае происходит аутентификация.
$gPAUSE.. сегодня сяду переписывать и от многого избавлюсь. Код выложу,- сравнить можно будет %).

> sOff я бы писал по-другому. Ты чего-то слишком замудрил.
> Проще было бы просто прописывать в .hash-файл новое время
> последнего обращения, превышающего по таймауту $cFSession,
> а после выводить сообщение типа "ошибка авторизации" или
> "вы удачно вышли" (добавить ещё одно условие несложное) и в
> конце вызывать exit().
Ну дык для выхода тоже нужно пройти процедуру аутентификации, иначе все начнут друг друга «выходить» %). Или я непрально понял?

> Что касается времени, то тут я даже не пытался разбираться
> - с детства проблемы были с арифметикой, но вроде как ты
> учитываешь только день и число секунд после полуночи (вроде
> как судя по аргументам, но опять же я не пытался
> разобраться). Я бы вообще localtime не вызывал, а
> использовал бы (time/60-n) (n - количество минут,
> проходящих лет за десять - что бы число было поменьше). А
> ещё лучше применить побитовый сдвиг, но это уже моя личная
> параноя (люблю всё оптимизировать :-)).
У меня идёт учёт минут дня и номера дня/месяца. Оптимизировать, конечно, не помешало бы.. Подумаю над этим.

> Теперь поговорим непосредственно о безопастности. Если
> такую аутентификацию применять в форуме/чате/гостевой
> книге, то есть все шансы, что злоумышленник :-) сможет
> впихнуть на страницу вызов внешнего CGI-скрипта и прочитать
> твою адресную строку. А заодно инфу о браузере и IP. Таким
> образом хэш уже известен, инфу о браузере можно подделать,
> а в случае использования клиентом анонимного прокси, ещё и
> айпишник. Хотя вроде как я наслышан, что IP подделывают,
> что-то там подправляя в каких-то пакетах, но это уже не моя
> область.
Подделка IP,- вещь несложная.
Но хАкИр не знает по какому принципу формируется хеш, не знает ничего о контрольном числе, хотя это и можно обойти, но от такого тех.уровня хАкИра никто не застрахован %).

> Что бы этого избежать можно либо применять кукисы, либо
> метод POST отправки формы. Тогда ссылка будет выглядеть как
> <a href="javascript:xxx(hash,url)">. Сам скрипт:
>
> <script language=javascript>
> function xxx(hash,url) {
> document.f1.action=url;
> //не помню точно, как записывается
> //action надо будет доки почитать
> document.f1.h1.value=hash;
> document.f1.submit();
> }
> </script>
>
> Ну и должна присутствовать форма:
>
> <form name=f1 method=post>
> <input type=hidden name=hash>
> </form>
>
> Это, конечно, уже извращения, однако работает и вполне
> надёжно. (я так всё подробно излагаю, потому что хочу
> статью потом из этого замуть) Кстати в случае применения
> кукисов, можно вообще таймаут не использовать - время их
> жизни может достаточно жёстко задаваться, однако я бы на
> это полагаться не стал.
Не.. куки я использовать не буду %).
А про яву.. блин.. как мне надоели эти прибамбасы ;(.. Подумаю..

> Но это всё больше ребячество. Теперь про действительно
> серьёзную и уже ошибку. Посмотри на функцию аутентификации:
> она НЕ ПРОВЕРЯЕТ КОНТРОЛЬНОЕ ЧИСЛО!! Она его использует
> только для генерации хеша, причём само контрольное число
> высчитывается заново в начале аутентификации. Дальше
> вызывается crypt($all,$rnd) (не помню как переменная со
> случайным числом называется) и сравнивает результат с
> переданным пользователем хешем. Зная алгоритм
> аутентификации (а предполагается, что я его знаю), я могу
> посчитать контрольное число для себя (используя СВОЙ IP,
> ведь число пересчитывается до проверки!!). Функцию crypt я
> тоже знаю - она по твоим словам из стандартной библиотеки к
> тому же. Дальше я пишу простой эксплоит, который используя
> МОЁ контрольное число перебирает все подряд значения $rnd
> (их всего 99 - перебор займёт две минуты на модеме с плохой
> связью), шифрует их известной функцией crypt и открывает
> страницу, отправляя полученный хеш. В одном из 99
> вариантов, мой хеш подойдёт. Защиты от брутфорса твоя
> функция аутентификации не имеет - перебрать все значения
> мне никто не помешает. Даже если случайное число будет
> выбираться из более крупного диапазона, перебор займёт не
> так уж много времени.
Нифига %). Функция sHASH как раз для предотвращения этого и написана %).
А строку $gRND= int(rand(99)); я просто забыл переместить в модуль авторизации, при аутентификации КЧ загружается из hash-файла.

> Исправить ошибку можно отменив пересчёт контрольного числа
> заново, но это не спасёт ситуацию - IP можно подделать, а
> проверка HTTP_USER_AGENT далеко не каждого остановит.
> Следует как минимум защититься от перебора.
>
> А вообще наличие криптографии в данном случае себя имхо не
> оправдывает - хеш можно делать вообще СЛУЧАЙНЫМ числом - от
> этого никто не пострадает, только процессор разгрузится, а
> контрольное число проверять независимо. Хотя наличие
> контрольного числа в таком виде как оно есть уже являет из
> себя серьёзную угрозу. Я, допустим, не умею подделывать IP,
> но умею подделывать HTTP_USER_AGENT. Контрольное число -
> это сумма ASCII-значений символов в трёх переменных
> окружения. Причем основной вес ему придаёт именно тот самый
> HTTP_USER_AGENT. Подделав его, я могу даже без подделки IP
> добиться нужного мне контрольного числа.
>
> Вывод: делай защиту от перебора (как только передаётся
> ошибочный хеш - руби сессию), не надо каждый раз
> пересчитывать контрольное число - пользуй то, которое
> получил при авторизации, IP проверяй независимо от
> контрольного числа (в том числе и проксю). Желательно
> конечно ещё передавать хеш не через адресную строку - но
> это достаточно муторно. Идеальный вариант - хеш после
> каждой аутентификации менять, но тогда пользователи
> потеряют функцию "открыть в новом окне", что не хорошо.
>
> Фуф.. вроде всё... Вот такое вот исследование безопастности
> %)
Круто ;).
Сёня вечером перечитаю и переработаю всё %).

> ЗЫ. Однако если кто-то вклинится в траффик, такая защита
> становится уже не актуальной.
Ну от этого мало кто защищён %).

> ЗЗЫ. А чего за crypt? Хотя бы в какой библиотеке?
В стандартной, в той, в которой вся математика, видимо.. Я не смотрел ещё.
Пожалуйста :-) 14.07.04 23:19  
Автор: Heller <Heller> Статус: Elderman
<"чистая" ссылка>
> Сразу выражу благодарность за помощь: Спасибо.
Пожалуйста :-)

> Я чувствую (всё ещё не прочитал), что намеченная ревизия
> этого модуля будет проходить долго и кропотливо %).
Угу :-)

> Храню в разных файлах, тк hash-файлы содержат пароль,
> уровень доступа (УД), контрольное число (КЧ), и контрольное
> время/дату (КВД), т.е. важные данные, при потере которых
> будут проблемы. А в auth-файле хранится всего лишь краткая
> инфа: логин, дата регистрации и статус.
А Ты вот ещё о чём подумай: вдруг один из .auth-файлов прапал или просто надо удалить пользователя.. Тогда твой цикл в GetUID (вроде так, не помню) сразу обломается. Так что всё же я делал бы профайлы, у которых имя - это логин, а внутри уже всё остальное.

>> По поводу sOff...
> Ну дык для выхода тоже нужно пройти процедуру
> аутентификации, иначе все начнут друг друга «выходить» %).
> Или я непрально понял?
Неправильно. Просто поменяй контрольное время в .hash-файле выходящего пользователя и всё. Хотя это не значительно.

> Подделка IP,- вещь несложная.
> Но хАкИр не знает по какому принципу формируется хеш, не
> знает ничего о контрольном числе, хотя это и можно обойти,
> но от такого тех.уровня хАкИра никто не застрахован %).
Ну о хеше я ниже уже писал, а что до контрольного числа - то предполагается, что код у Тебя открытый, а выяснить инфу о другом пользователе несложно. Я могу общаться с нгим по аське и ненароком спросить о версии браузера и об используемом прокси.

> Не.. куки я использовать не буду %).
Кстати я на своём серваке собирал как-то статистику пол-года назад.. Процент использования кукисов - 100% (из тех, кто просматривал хотя бы две страницы сайта). А что до надёжности - то перехватить кукисы на практике посложнее чем ту же адресную строку.

> А про яву.. блин.. как мне надоели эти прибамбасы ;(..
> Подумаю..
Да это не критично, имхо. Меня просто чего-то в дубри потянуло, всё таки в восемь утра писал :-)

> Нифига %). Функция sHASH как раз для предотвращения этого и
> написана %).
> А строку $gRND= int(rand(99)); я просто забыл переместить в
> модуль авторизации, при аутентификации КЧ загружается из
> hash-файла.
Угу. Забыл :-) Вот так ошибки и рождаются :-)

> Круто ;).
> Сёня вечером перечитаю и переработаю всё %).
ok. Постараюсь вечерком покопать исправленный код.

> > ЗЫ. Однако если кто-то вклинится в траффик, такая
> защита
> > становится уже не актуальной.
> Ну от этого мало кто защищён %).
Да не так уж и сложно защититься - просто траффик весь шифровать да и всё.

crypt тогда позже посмотрю.

ЗЫ. Ещё раз о префиксе @. Мой Perl (как под виндой, так и под шапкой) отказывается понимать запись @array[i]. Пишет, что мол эррор :-) Воспринимает только $array[i]
На данный момент, учтя замечания, сделал так: 15.07.04 04:08  
Автор: !? <!?> Статус: Member
<"чистая" ссылка>
> А Ты вот ещё о чём подумай: вдруг один из .auth-файлов
> прапал или просто надо удалить пользователя.. Тогда твой
> цикл в GetUID (вроде так, не помню) сразу обломается. Так
> что всё же я делал бы профайлы, у которых имя - это логин,
> а внутри уже всё остальное.
На данный момент, учтя замечания, сделал так:
idlist- лист вида ID•LOGIN
auth-файлы вида ID.auth- данные об аккаунте (Логин, Дата регистрации, Статус, УД). Логин на случай потери idlist'а, для его восстановления.
hash-файлы вида ID.hash- хеш пароля, КЧ и время сессии. При окончании сессии в hash-файле остаётся только хеш.

> >> По поводу sOff...
> > Ну дык для выхода тоже нужно пройти процедуру
> > аутентификации, иначе все начнут друг друга «выходить»
> %).
> > Или я непрально понял?
> Неправильно. Просто поменяй контрольное время в .hash-файле
> выходящего пользователя и всё. Хотя это не значительно.
Время меняется при каждой успешной аутентификации (если таймаут ещё не истёк), а при выходе,- удаляется.

> > Подделка IP,- вещь несложная.
> > Но хАкИр не знает по какому принципу формируется хеш,
>> не
> > знает ничего о контрольном числе, хотя это и можно
> > обойти,
> > но от такого тех.уровня хАкИра никто не застрахован
> > %).
> Ну о хеше я ниже уже писал, а что до контрольного числа -
> то предполагается, что код у Тебя открытый, а выяснить инфу
> о другом пользователе несложно. Я могу общаться с нгим по
> аське и ненароком спросить о версии браузера и об
> используемом прокси.
Не думаю, что чтонть типа этого можно узнать по аське: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.9.2
Я думаю над тем, использовать ли HTTP_ACCEPT..
С ним были проблемы,- пользователи жаловались на постоянное «сбивание» авторизации. Разобрался,- оказалось в осле и ему подобных (MyIE до 2, ещё что-то, что я никогда не видел) эта переменная не передаётся при обновлении страницы..
Надо потестить, ща в miscellaneous топик создам.

> > Не.. куки я использовать не буду %).
> Кстати я на своём серваке собирал как-то статистику
> пол-года назад.. Процент использования кукисов - 100% (из
> тех, кто просматривал хотя бы две страницы сайта). А что до
> надёжности - то перехватить кукисы на практике посложнее
> чем ту же адресную строку.
Не в моих принципах что-то скрывать %).
Я хочу показать, но защищённое.

> > Круто ;).
> > Сёня вечером перечитаю и переработаю всё %).
> ok. Постараюсь вечерком покопать исправленный код.
Я его уже положил. В самой ближней ветке к корню.

> > > ЗЫ. Однако если кто-то вклинится в траффик, такая
> > > защита
> > > становится уже не актуальной.
> > Ну от этого мало кто защищён %).
> Да не так уж и сложно защититься - просто траффик весь
> шифровать да и всё.
На данный момент, думаю, для меня это будет слишком сложно..

> crypt тогда позже посмотрю.
>
> ЗЫ. Ещё раз о префиксе @. Мой Perl (как
> под виндой, так и под шапкой) отказывается понимать запись
> @array[i]. Пишет, что мол эррор :-)
> Воспринимает только $array[i]
Странно. У меня какие-то из пятых интерпретаторов, все воспринимают одинаково. На трёх разных системах. Вот так вот ;).
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 1 s   Design: Vadim Derkach