Napredna prijava z "Remember Me"

Dober dan,

Mene zanima ena stvar, in sicer poskušam nardit zelo varno prijavo z možnostjo "Remember me" torej sestava je takšna:

Po prijavi usvtarim sejo z informacijami o uporabniku (ID uporabnika (random generiran ali pa Facebook account id), temporary ključ (popovnoma random z trenutnim časom in ip naslovom uporabnika, seveda enskriptan z base64 in pa ključem, hkrati pa ustvarim tudi cookie z informacijo temporary ključa. Torej če uporabnik ne označi "Remember me" bo po potečeni seji (po zaprtju browserja) ta potekla. V bazi pa je ta seja omejena na en dan. Če je pa "Remember me" označen pa se shrani v bazi podatek da je potek seje čez 30 dni, in pa ko uporabnik pride nazaj, brez seje se zgodi naslednje:
Preverim cookie, če je key enak kod v bazi, ustvarim nov temporary key z expiracijo iz baze (torej še 29 dni) in tudi shranim nov temporary key v cookie.

Samo zanima me ena zadeva, glede na to da se da cookie ukrast, kakšna je možnost za to? Se da kako zaščitit da bi recimo v bazo shranil nekaj unikatnega za vsakega uporabnika? In pa prenašam vse skupaj prek HTTPS če je le možno. Problem pa nastane ko uporabnik pride po potečeni seji, ker ne glede na protokol se ponovno ustvari cookie z novim "keyom" ki pa ni prenešen preku https protokola, je to velika luknja v varnosti?

Če želite več lahko tudi postam kodo. Samo da rešim tole, ker rabim res varno prijavo tudi za kasneje.

LP.
Jaka.

16 odgovorov

Cookie ima že itak expiration date, ki ga lahko nastaviš po želji, ne vem zakaj bi kompliciral z bazo. Pa tudi, ko zapreš brskalnik se cookie ne zbriše (default nastavitve). Ne kompliciraj z nekimi temporary keyi, ker s tem ne pridobiš na varnosti ampak samo zakompliciraš zadevo. Base64 prav tako pozabi.

Zelo pa pridobiš na varnosti, če celotna povezava kjer se prenaša cookie poteka prek SSL, saj ti ne more nihče secure povezave sniffat.

Na varnosti boš pridobil tudi, če uporabiš kakšen salt pri enkripciji gesel v bazi in pa uporabiš sha256, sha512, blowfish oz. enega od novejših hashing algoritmov.

Upam, da sem ti kaj pomagal.
lp

3

O ja ^^ Zelo. Za bazo uporabljam Hash sha512 z saltom tako da to me ne skrbi, bol za avtorizacijo pa to. Torej če dam v cookie uporabniški ID z base64() salt enskripcijobi moglo bit dovol varno? Prijava seveda poteka preku SSL oz. TLS

Base64 je brezveze, ker le malo zamenja črke in obfuskira string. Komot pa daš uporabniški id v cookie, saj se tam v vsakem primeru še dodatno zakrije, tako da res ni potrebe po base64. (Base64 NI mišljen za enkripcijo). Tudi če prijava poteka prek SSL, pa se potem cookie ohranja še pri plaintext povezavah, ti ga lahko kdo posniffa in ukrade in s tem dobi session. Tako da, če bi rad mel res secure zadevo, imej vse prek SSL, če pa ni varnost res kritičnega pomena potem je pa tole kar si si zamislu čist uredu.

3

Ok ^^ Hvala za pomoč.

Drugače pa ne uporabljam direktno base64 ampak imam nekaj takega:

ivlen = 35
password = 3|@4'
|F56zkr23sal31'*?v:b/$in%tdHELX&"! (samo primer)

// Encryption encrypt
    //////////////////////////////////////////////////////////////////////////////////////////////////
    function enc_e( $plain_text ) {
        global $site;

        $password = $site[enc_pass];
        $iv_len   = $site[enc_len];

        $plain_text .= "\x13";
        $n = strlen( $plain_text );
        if ( $n % 16 )
            $plain_text .= str_repeat( "\0", 16 - ( $n % 16 ) );
        $i        = 0;
        $enc_text = get_rnd_iv( $iv_len );
        $iv       = substr( $password ^ $enc_text, 0, 512 );
        while ( $i < $n ) {
            $block = substr( $plain_text, $i, 16 ) ^ pack( 'H*', md5( $iv ) );
            $enc_text .= $block;
            $iv = substr( $block . $iv, 0, 512 ) ^ $password;
            $i += 16;
        }
        return base64_encode( $enc_text );
    }

    // Encryption Decrypt
    //////////////////////////////////////////////////////////////////////////////////////////////////
    function enc_d( $enc_text ) {
        global $site;

        $password = $site[enc_pass];
        $iv_len   = $site[enc_len];

        $enc_text   = base64_decode( $enc_text );
        $n          = strlen( $enc_text );
        $i          = $iv_len;
        $plain_text = '';
        $iv         = substr( $password ^ substr( $enc_text, 0, $iv_len ), 0, 512 );
        while ( $i < $n ) {
            $block = substr( $enc_text, $i, 16 );
            $plain_text .= $block ^ pack( 'H*', md5( $iv ) );
            $iv = substr( $block . $iv, 0, 512 ) ^ $password;
            $i += 16;
        }
        return preg_replace( '/\\x13\\x00*$/', '', $plain_text );
    }

Lahko bi ob prijavi tudi IP preverjal.
Npr., določen ključ iz cookija dela samo iz tistega ip-ja od kod je bil kreiran.

Ima pa to svoje pluse in minuse.

Mogoce bi zdraven dodal zakodirano ime racunalnika in preverjal ce je iz enakega racunalnika/naprave to bi bil en tak zanimiv trik se mi zdi :)

Kako bi pa v browser dobil ime računalnika/naprave?

Tukaj je govora o tem predlagam da pogledas komentarje.
http://lostwithin.net/how-to-get-users-ip-and-computer-name-using-php/

1

Oj, sem pogledal in preveril primere... in še vedno ne vem kako dobiti ime :)
Še vedno mislim, da se imena računalnika ne da dobiti s PHPjem.

Mogoče bi se dalo kako do MAC-a dokopat, ampak tako globoko se mi pa neda it raziskovat :)

V teh komentarjih ce je resitev, drugace pa res ne gre :)