michalkkk
8.12.2004, 22:16:27
Witam. Ostatanio zastanawiam sie nad stworzeniem bezpiecznego formularza logowania(bez wykorzystania ssl poniewaz trzeba kupowac certyfikaty aby nie pojawiały sie ostrzeżenia przegladarek). Pomimo tytułu uważam że skrypt jest do zlamania(tak myśle, nie próbowałem), ale chciałem poznać Wasze rady, wskazówki. Może z Waszą pomocą uda mi(nam) się napisać w miarę bezpieczny formularz logowania-taki szablon ktory bedzie kazdy mogl zastosowac u siebie. Starałem się wykorzystac Wasze wskazówki, które pisaliście w innych postach. Wykorzystałem chyba troche rzadko stosowana metode z szyfrowaniem(md5-http://pajhome.org.uk/crypt/md5) niektorych przesyłanych danych w javascript po stronie klienta. Cały czas myśle co by mozna jeszcze udoskonalić, także licze na Waszą pomoc. Z góry dzięki.
Chce jak najbardziej utrudnić możliwość zalogowania przez podsłuchanie danych(brak ssl), dlatego szyfruje ip,referer,idsesji. Moze np. odczytac za pomoca JavaScript(aby nie przesyłać danych z serwera do klienta) wersje przegladarki, zaszyfrowac md5(w js) a potem odczytac za pomoca php(ale chyba przy odczycie wersji przez php tez jest przesyłana informacja) i porównac. Nie znam sie za bardzo na tym, ale czy mozna zasymulowac lub podstawić id sesji aby oszukac skrypt? Ip,referer chyba tak.
Sciezka do pliku powinna byc taka jak wpisana w poniższym pliku(oczywiscie trzeba wpisac wlasny adres)-http://jakasstrona.pl/log.php
<?
$ip=gethostbyaddr
(getenv (\"REMOTE_ADDR\")); $ref=$_SERVER['HTTP_REFERER'];
$ua=$_SERVER['HTTP_USER_AGENT'];
if ($_SESSION['nie_zmieniaj_losowej']!='tak')
{
$losowa=mt_rand(); //losuje kilkucyfrowa liczbe $_SESSION['ses_losowa']=$losowa;
}
$_SESSION['nie_zmieniaj_losowej']='tak';
//po kliknieciu w przycisk Loguj nastepuje
//wywolanie funkcji w javascript md5 - po stronie uzytkownika,
//która zestepuje wpisane przez uzytkownika haslo w zakodowany md5 ciag znaków
//do hasla przed zakodowaniem w javascript dodawane sa dodatkowe zmienne
//i to wszystko razem jest kodowane md5(w javascript) i wysylane do serwera
//niezaszyfrowane haslo nie jest wysyłane
?>
<script src=\"md5.js\" type=\"text/javascript\"></script>
<FORM METHOD=POST>
Login: <input type=\"text\" name=\"login\" value=\"\">
Haslo: <input type=\"text\" name=\"_haslo\" value=\"\">
<input type=\"hidden\" name=\"haslo\" value=\"\">
<input type=\"submit\" value=\"LOGUJ\" onclick=\"haslo.value = hex_md5(_haslo.value+'
<?echo $zak_ip.$zak_ref.$_SESSION['ses_losowa'].$zak_ua?>'); _haslo.value = ''\">
</FORM>
<?
//////poprawny login i haslo(normalnie bedzie odczytywane z bazy danych)
$poprawny_login='michal';
$poprawne_haslo='test123';
//////poprawny login i haslo(normalnie bedzie odczytywane z bazy danych)
/////sprawdzanie czy poprawne dane
if ($_POST['login'] || $_POST['haslo'])
{
$kod_poprawny=md5($poprawne_haslo.md5($ip).md5($ref).$_SESSION['ses_losowa'].md5($ua));
if ($_POST['haslo']==$kod_poprawny && $_SERVER[\"HTTP_REFERER\"]=='http://jakasstrona.pl/log.php' && $_POST['se']==session_id())
{
echo 'Zostales zalogowany!'; }
else
{
}
}
/////sprawdzanie czy poprawne dane
?>
Speedy
11.12.2004, 16:18:03
Wg mnie hasła, niezależnie od tego czy znajdują się w bazie , czy też w samym skrypcie powinny być również zaszyfrowane, ponieważ taka chyba jest idea algorytmów szyfrujących

. Jeśli potencjalny włamywacz dostałby się jakoś do bazy , to zaszyfrowane hasła są kolejnym problemem dla niego

.
Skrypt powinien szyfrować wpisane dane , a następnie sprawdzać , czy zgadzają się one z podanym ciągiem znaków, który już będzie podany w postaci zaszyfrowanej. Nie powinno się podawać nigdzie niezaszyfrowanej wersji hasła.
Czyli zamiast np. :
<?php
$poprawny_login='michal';
$poprawne_haslo='test123';
$podany_login='$login';
$podane_haslo='$haslo';
$podany_login_hash=md5($login); $podane_haslo_hash=md5($haslo);
$poprawny_login_hash=md5($poprawny_login); $poprawne_haslo_hash=md5($poprawne_haslo);
if ($poprawny_login_hash==$podany_login_hash) {
if ($poprawne_haslo_hash==$podane_haslo_hash) {
}
} else {
print 'niepoprawne dane'; }
?>
Powinno być mniej więcej coś takiego :
<?php
$poprawny_login='06b2af75179fb94be097af182a442a4a';
$poprawne_haslo='cc03e747a6afbbcbf8be7668acfebee5';
$podany_login='$login';
$podane_haslo='$haslo';
$podany_login_hash=md5($login); $podane_haslo_hash=md5($haslo);
if ($poprawny_login==$podany_login_hash) {
if ($poprawne_haslo==$podane_haslo_hash) {
}
} else {
print 'niepoprawne dane'; }
?>
Napisałem to tak "na oko" , ale mam nadzieję, że uchwycisz ideę

.
PS.
06b2af75179fb94be097af182a442a4a == md5(michal);
cc03e747a6afbbcbf8be7668acfebee5 == md5(test123);
Pozdrawiam

.
bregovic
11.12.2004, 17:09:28
Generalnie haszowanie hasła przed wysłaniem go dna serwer to bardzo dobry pomysł. Jedyny problem pojawia sie jesli user ma wylaczony javascript (a tacy sa).
Zresztą wystarczy odpalić jakikolwiek sniffer w sieci lokalnej aby wyłąpać masę haseł.
Kiedyś myślałem nad takim bezpiecznym formularzem - trzeba w nim przekazać jak najwięcej danych o użytkowniku, więc patrzymy sobie w
phpinfo" title="Zobacz w manualu PHP" target="_manual i wyciągamy jak największą ilość ciekawych żeczy:
<?php
$_SERVER[\"HTTP_USER_AGENT\"];
$_SERVER[\"HTTP_ACCEPT_LANGUAGE\"];
$_SERVER[\"HTTP_ACCEPT_CHARSET\"];
?>
Za to nie radzę używać HTTP_REFERER - nie jest przecierz powiedziane że user nie wszedł bezpośrednio na strone...
No i powinieeś jednak użyć
sha1" title="Zobacz w manualu PHP" target="_manual - jest bezpieczniejszy, i można goteż sciągnąć dla javascriptu - z podanej przez ciebie strony.
Dobrym pomysłem, imo, jest też sprawdzanie tych wartości za każdym startem sesji.
Speedy
11.12.2004, 18:32:19
Wystarczy nieco przerobić ten skrypt i można w ogóle wyzbyć się w nim javascript'u . Sprawdzanie poprawności hasła można dokonać za pomocą funkcji dostępnych w php

.
http://pl2.php.net/manual/pl/function.md5.phphttp://pl2.php.net/manual/pl/function.sha1.phpMożna jeszcze skorzystać z autoryzacji dostępnej w php .
Przy okazji polecam lekturę :
http://www.maciaszek.pl/phpcon/download/autoryzacja.pdfPozdrawiam .
dooshek
11.12.2004, 18:52:40
Cytat(bregovic @ 2004-12-11 18:09:28)
Generalnie haszowanie hasła przed wysłaniem go dna serwer to bardzo dobry pomysł. Jedyny problem pojawia sie jesli user ma wylaczony javascript (a tacy sa).
Zresztą wystarczy odpalić jakikolwiek sniffer w sieci lokalnej aby wyłąpać masę haseł.
Kiedyś myślałem nad takim bezpiecznym formularzem - trzeba w nim przekazać jak najwięcej danych o użytkowniku, więc patrzymy sobie w
phpinfo" target="_blank - jest bezpieczniejszy, i można goteż sciągnąć dla javascriptu - z podanej przez ciebie strony.
Dobrym pomysłem, imo, jest też sprawdzanie tych wartości za każdym startem sesji.
No generalnie panowie bardzo fajnie tylko co jesli ktos przechwyci ten md5 (za pomoca sniffera zaden problem) i po prostu wysle do serwera ten MD5 ktory podal uzytkownik? Wtedy nie musi znac nazwy uzytkownika ani hasla - przesyla do serwera te md5tki, sha1cze czy co tam jeszcze i i tak sie np. zaloguje...
Speedy
11.12.2004, 19:29:48
Cytat(dooshek @ 2004-12-11 17:52:40)
Cytat(bregovic @ 2004-12-11 18:09:28)
Generalnie haszowanie hasła przed wysłaniem go dna serwer to bardzo dobry pomysł. Jedyny problem pojawia sie jesli user ma wylaczony javascript (a tacy sa).
Zresztą wystarczy odpalić jakikolwiek sniffer w sieci lokalnej aby wyłąpać masę haseł.
Kiedyś myślałem nad takim bezpiecznym formularzem - trzeba w nim przekazać jak najwięcej danych o użytkowniku, więc patrzymy sobie w
phpinfo" target="_blank - jest bezpieczniejszy, i można goteż sciągnąć dla javascriptu - z podanej przez ciebie strony.
Dobrym pomysłem, imo, jest też sprawdzanie tych wartości za każdym startem sesji.
No generalnie panowie bardzo fajnie tylko co jesli ktos przechwyci ten md5 (za pomoca sniffera zaden problem) i po prostu wysle do serwera ten MD5 ktory podal uzytkownik? Wtedy nie musi znac nazwy uzytkownika ani hasla - przesyla do serwera te md5tki, sha1cze czy co tam jeszcze i i tak sie np. zaloguje...
W moim pomyśle ta opcja odpada ponieważ podajesz skryptowi jakąś frazę, a on ją szyfruje i sprawdza czy zgadza się z zaszyfrowanym wcześniej ciągiem , który jest w jakiejś bazie. md5 da się rozszyfrować, ale ciężko, więc sam zaszyfrowany ciąg takiemu "hackerowi" na niewiele się zda. Jeśli podasz skryptowi ciąg zaszyfrowany, to on go zaszyfruje i sprawdzi , czy "podwójnie zaszyfrowane" hasło zgadza się prawidłowym hashem. Oczywiście nie będzie się zgadzać

. Problem pojawia się jeżeli zostanie przechwycone niezaszyfrowane hasło. Ale i tak sprawa sniffer'ów dotyczy tylko sieci i tą sprawę należy rozpatrywać inaczej. Jeśli ktoś łączy się z internetem w inny sposób - problem znika

.
bregovic
11.12.2004, 21:33:38
Szyfrowanie po stronie przeglądarki jest potrzebne - żeby zaciemnić hasło i dane które razem z nim wysyłamy jako klucz. Wysyłamy zahaszowane wartości jak najbliższe pełnoprawnemu userowi, jak HTTP_USER_AGENT. Dodatkowo w jakimś polu hidden wysyłamy randomową liczbę oznaczającą jakiś string na serwerze (np id pola w tabeli mysql) który doklejamy do hasza - to jesteśmy w domu.
Czyli konkludując wracamy do tego co michalkkk napisał w swoim pierwszym poście.
--- EDIT ---
Speedy, próbowałe kiedykolwiek włączyć jakikolwiek sniffer w sieci lokalnej? To na prawde powiększa perspektywę znaczenia słowa 'bezpieczeństwo'...
michalkkk
11.12.2004, 22:09:32
Dziekuje za Wasze wskazówki, jeszcze troche postaram sie udoskonalić skrypt. Oczywiście umieszcze go tutaj. Pozdrawiam, Michal
hawk
11.12.2004, 22:58:37
Tak sobie czytam i zastanawiam się, co rozumiecie przez "bezpieczne logowanie". Bo ja w sumie nie wiem, a bezpieczeństwo nie polega wcale na jednym formularzu logowania.
Nie wiem, czy to jest do złamania, czy nie, ale to nieistotne. Po co się męczyć? Posiadacz snifferka poczeka, aż się zalogujesz, potem wyśle ci pakiet zamykający połączenie TCP, a do serwera wyśle co mu się żywnie podoba. Koniec.
SSL nie wymyślili tylko dlatego, że nie lubili javascriptu.
Imperior
12.12.2004, 10:31:17
@hawk:
No cóż... tutaj jest przedstawiony sposób na bezpieczeństwo logowania, co jest najłatwiej zrobić, a bezpieczeństwo sesji to już jest inna para kaloszy i wyższa szkoła jazdy (bez SSL oczywiście).
Jabol
12.12.2004, 15:09:05
A pozatym co za problem, jeżeli przechwyce hasło zahaszowane w md5? Po prostu zrobie małą zmianę np. w kopii lokalnej formularza z serwera i podam zamiast hasła wersję już zahaszowaną.
Tzn. wpiszę w pole hasło już zahaszowaną wersję hasła i zrobię taki bajerek, że js już nie będzie tego chciał znowu haszować.
Jeżeli jeszcze napiszę sobie programik, który będzie wysyłał dowolne nagłówki do serwera to już system logowania można uznać za złamany.
A jeżeli już chcecie czarną wizję:
hawk, co Ci da ssl, jeżeli zatruje ARP, zamiast do serwera podłączysz się do mnie, u mnie wszystkie dane będą odszyfrowane, odczytane i przekierowane do serwera docelowego. Ale ja będę znał całą tranzakcję.
No, chyba, że już się bawimy w SSL na poważnie, czyli z certyfikatami po obu stronach i takie tam. Wtedy zaczyna być bezpiecznie.
hawk
12.12.2004, 17:05:32
@Imperior: bezpieczeństwo logowania samo w sobie jest kompletnie bez znaczenia. Liczy się bezpieczeństwo aplikacji. Nie warto inwestować w poprawę bezpieczeństwa w jednym miejscu, gdy obok mamy poważną dziurę. Trzeba pamiętać, czemu skrypt logowania ma służyć.
@Jabol: mówisz o typowym man-in-the-middle dla SSL? Wtedy potrzebny jest jakiś legalny certyfikat, żeby klient łączył się z tobą przez SSL. Trochę pomaga dziura w MSIE... czy podany przez ciebie ARP spoofing omija to?
Coś ciężko mi się dzisiaj myśli, idę znaleźć trochę glukozy
Imperior
12.12.2004, 20:28:26
@hawk: Doskonale zdaję sobie z tego sprawę. Dręczy mnie właśnie jak zabezpieczyć sesję na możliwie jak najwyższym poziomie i w miarę komfortowej pracy. IMHO to jest największa słabość w użyciu HTTP w połączeniu z przeglądarką bez użycia SSL (W przypadku własnych programów to co innego, bo tam za każdym wywołaniem można przesyłać dane).
hawk
13.12.2004, 09:24:57
BTW, SSL != bezpieczeństwo sesji. Użycie SSL nie załatwia problemu, i nie uniemożliwia ataków typu session fixation.
Imperior
13.12.2004, 17:30:49
Rzecz jasna, że SSL nie załatwia sprawy, ale chyba zgodzisz się, że SSL drastycznie poprawia bezpieczeństwo?
Jeżeli sesje oparte są tylko na sid, to jest możliwość, że ktoś przejmie sesję, ale przynajmniej w dużym stopniu możemy wykluczyć podsłuchanie komunikacji. Przecież samym php nie zdziałamy cudów... Użytkownik też musi dbać o bezpieczeństwo.
dooshek
13.12.2004, 18:29:31
Cytat(Speedy @ 2004-12-11 20:29:48)
W moim pomyśle ta opcja odpada ponieważ podajesz skryptowi jakąś frazę, a on ją szyfruje i sprawdza czy zgadza się z zaszyfrowanym wcześniej ciągiem , który jest w jakiejś bazie. md5 da się rozszyfrować, ale ciężko, więc sam zaszyfrowany ciąg takiemu "hackerowi" na niewiele się zda. Jeśli podasz skryptowi ciąg zaszyfrowany, to on go zaszyfruje i sprawdzi , czy "podwójnie zaszyfrowane" hasło zgadza się prawidłowym hashem. Oczywiście nie będzie się zgadzać

. Problem pojawia się jeżeli zostanie przechwycone niezaszyfrowane hasło. Ale i tak sprawa sniffer'ów dotyczy tylko sieci i tą sprawę należy rozpatrywać inaczej. Jeśli ktoś łączy się z internetem w inny sposób - problem znika

.
Nie rozumiesz - nic nie musisz "rozszyfrowywac" - wystarczy przechwycic Twoj czy tez md5 snifferem i zapodac do Twojego skryptu ktory bedzie "myslal", ze pochodzi on od uzytkownika... W rzeczywistosci bedzie pochodzil od hackera ktory bez podawania hasla sie dostanie na stronke. Mozesz to szyfrowac i rozszyfrowywac miliony razy - to nic nie da dopoki transmisja nie bedzie bezpieczna.
Co do snifferow i braku problemu podsluchiwania to nie bylbym pewien czy "problem znika" - podejrzewam, ze da sie podsluchac Cie jak uzywasz modemu, neo czy tez innego "dostepu" - pakiety przechodza przez rozne miejsca wiec nie sadze, ze to nie jest problem a jesli rozpatrujesz "bezpieczne" logowanie to Twoje takie nie jest niestety
Jabol
13.12.2004, 20:34:44
@hawk: tak, mówię o zwykłym man-in-the-middle dla SSL, z tym, że dla pierwszej sesji, kiedy użytkownik nie zna jeszcze certyfikatu drugiej strony. Oczywiście jeżeli ktoś sobie pójdzie do firmy i spisze na karteczce spisze figerprint to już na to nie zdziałam o ile nie mam ich certyfiaktu (conajmniej na moją wiedzę), a zatruwawnie ARP nic na to działa, to powoduje tylko, że zamiast do serwera pakiety płyną do mnie.
@dooshek: Jeżeli sobie zrobisz jakiś ładny tunel ssh to do bezpiecznego już miejsca (najlepiej do końca) to nic takie "niebezpieczne lokalizacje" nie zdziałają.
hawk
14.12.2004, 09:12:24
@Jabol: AFAIK problem z man-in-the-middle był taki, że trzeba przedstawić użytkownikowi jakiś certyfikat. Nawet jak nie sprawdzi, co jest wpisane w środku. I ten fałszywy certyfikat musi być wystawiony przez jakieś centrum certyfikacyjne, bo inaczej przeglądarka zgłosi błąd. No chyba że użytkownik klika OK na każdy komunikat o błędzie, lub wykorzystamy dziurę IE, który dość liberalnie traktuje zasady, komu wolno wystawiać certyfikaty.
Tak czy siak, wymaga to chyba zaniedbania/ignorancji ze strony użytkownika. A swoją drogą, certyfikaty dla obu stron transakcji byłyby fajne

. Podobno w Estonii chcą wprowadzić elektroniczne dowody osobiste z zestawem kluczy do podpisu cyfrowego. Może niedługo to będzie realne?
Imperior
14.12.2004, 10:09:24
Cytat(hawk @ 2004-12-14 08:12:24)
Podobno w Estonii chcą wprowadzić elektroniczne dowody osobiste z zestawem kluczy do podpisu cyfrowego. Może niedługo to będzie realne?
Nie zdziwiłbym się. Estionia ma bardzo rozbudowaną sieć informatyczną w organizacjach państowych. My jesteśmy lata świetlne do tyłu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.