SORU
30 AĞUSTOS 2009, Pazar


&;" oturumumu Tutmak; - " en iyi yaklaşım

Benim web uygulama oturumları oturum hemen her kullanıcı hakkında bilgi saklamak için, ve app içinde sayfadan sayfaya Seyahat bu bilgileri tutmak için kullanır. Bu özel uygulama, kişinin user_id, first_name last_name depoluyorum.

İsterim ki, teklif "Tut Beni giriş" seçeneği açık oturum, koy çerez, kullanıcının makine için iki hafta, yeniden başlatma, oturum ile aynı ayrıntılar zaman geri dönmek için app.

Bunu yapmak için en iyi yaklaşım nedir? Bir kullanıcı başka bir kullanıcının kimliğini taklit etmek kolay olacak gibi görünüyor kurabiye user_id saklamak istemiyorum.

CEVAP
24 HAZİRAN 2013, PAZARTESİ


Eğer kullanıcı veri, ya da bir şey, bu amaç için bir çerez kullanıcı verilerden elde ediyorsun, bir şeyleri yanlış yapıyorsun. TAMAM, benden bu kadar açıkça koyalım:

Yok. Dedim. Şimdi gerçek cevap geçebiliriz.

Ne sen sor karma kullanıcı verileri ile oldu? Peki, maruz aşağı karanlık yüzey ve güvenlik geliyor.

Bir saldırgan olduğunu bir an için hayal edin. Bu şifreleme için bir çerez seti-Beni hatırla oturum görüşürüz. 32 bu karakter. Vay be. Bu bir MD5... olabilir

Umalım da kullanılan algoritma biliyorum, bir saniye için bile. Örneğin:

md5(salt username ip salt)

Şimdi, bir saldırganın yapması gereken ise kaba kuvvet "tuz" (hangi değil çok tuzlu, ama daha o daha sonra) ve artık görüyor oluşturmak tüm sahte jeton istiyor ile herhangi bir kullanıcı adı için IP adresi! Ama kaba-zorlama bir tuz zordur, değil mi? Kesinlikle. Ama günümüz GPU bu konuda artık çok iyi. Ve bu yeterli Turk kullanmadığınız sürece (yeterince büyük), hızlı ve kale anahtarları ile düşecek.

Kısacası, tek şey sizi korumak gerçekten düşündüğün kadar seni koruyamaz olan Tuz.

Ama Bekleyin!

Bütün bunlar saldırganın algoritmayı bildiği esas oldu! Eğer gizli ve karmaşık ise, o zaman güvenli, değil mi?YANLIŞ. Bu düşünce şekli bir adı vardır:Bilinmezlik Yoluyla Güvenlikhangi gerekirASLAgüvenilebilecek biri.

Daha İyi Bir Yol

Daha iyi bir yol hiç bir kullanıcı bilgileri sunucu kimliği dışında bırakalım.

Kullanıcı oturum açtığında, (256 bit 128) büyük rastgele belirteç oluşturmak. Kullanıcı kimliği belirteci haritalar, ve daha sonra tanımlama bilgisi istemciye göndermek veritabanı bir tablo ekleyelim.

Eğer saldırganın başka bir kullanıcı rastgele token tahmin ne?

Hadi biraz matematik yapalım. 128 bit rastgele bir belirteç üretiyoruz. Bu olduğu anlamına gelir:

possibilities = 2^128
possibilities = 3.4 * 10^38

Şimdi, ne kadar saçma sapan, büyük numara, hadi düşünün her server üzerinde internet (diyelim 50,000,000 bugün) çalışırken kaba kuvvet bu numaradan hızı saniyede 1,000,000,000 her. Gerçekte sunucularınız böyle bir yük altında eriyecek, ama hadi bunu oynayalım.

guesses_per_second = servers * guesses
guesses_per_second = 50,000,000 * 1,000,000,000
guesses_per_second = 50,000,000,000,000,000

Saniyede 50 katrilyon tahmin. Bu kadar hızlı! Değil mi?

time_to_guess = possibilities / guesses_per_second
time_to_guess = 3.4e38 / 50,000,000,000,000,000
time_to_guess = 6,800,000,000,000,000,000,000

Yani sekstilyon... 6.8 saniye

Hadi daha samimi sayıları aşağı getirmek için çalışıyoruz.

215,626,585,489,599 years

Hatta daha iyi:

47917

Evet, bu 47917 zamanlar evrenin yaşı...

Temelde, çatlak olacak.

Özetle:

Ben tavsiye iyi yaklaşım üç parça ile bir çerez saklamak için.

function onLogin($user) {
    $token = GenerateRandomToken(); // generate a token, should be 128 - 256 bit
    storeTokenForUser($user, $token);
    $cookie = $user . ':' . $token;
    $mac = hash_hmac('sha256', $cookie, SECRET_KEY);
    $cookie .= ':' . $mac;
    setcookie('rememberme', $cookie);
}

Sonra, doğrulamak için:

function rememberMe() {
    $cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
    if ($cookie) {
        list ($user, $token, $mac) = explode(':', $cookie);
        if (timingSafeCompare(hash_hmac('sha256', $user . ':' . $token, SECRET_KEY), $mac)) {
            return false;
        }
        $usertoken = fetchTokenByUserName($user);
        if (timingSafeCompare($usertoken, $token)) {
            logUserIn($user);
        }
    }
}

Not: kullanıcı belirteci veya birlikte kullanmayın ve veritabanındaki bir kaydı arama için simge. Her zaman emin bir rekor kullanıcıya göre almaya ve zamanlama güvenli bir karşılaştırma kullanmak token getirilen daha sonra karşılaştırmak için işlev. More about timing attacks.

ŞimdiçokSECRET_KEY şifreleme gizli olması önemli (/dev/random ve/gibi bir şey tarafından oluşturulan veya yüksek entropi bir giriş türetilmiştir). Ayrıca, GenerateRandomToken() güçlü rastgele bir kaynak (24* *neredeyse yeterince güçlü değildir. olması gerekir Bir kütüphane kullanın veya DEV_URANDOM ile mcrypt)...

Ve timingSafeCompare timing attacks önlemektir. Şöyle bir şey:

/**
 * A timing safe equals comparison
 *
 * To prevent leaking length information, it is important
 * that user input is always used as the second parameter.
 *
 * @param string $safe The internal (safe) value to be checked
 * @param string $user The user submitted (unsafe) value
 *
 * @return boolean True if the two strings are identical.
 */
function timingSafeCompare($safe, $user) {
    // Prevent issues if string length is 0
    $safe .= chr(0);
    $user .= chr(0);

    $safeLen = strlen($safe);
    $userLen = strlen($user);

    // Set the result to the difference between the lengths
    $result = $safeLen - $userLen;

    // Note that we ALWAYS iterate over the user-supplied length
    // This is to prevent leaking length information
    for ($i = 0; $i < $userLen; $i  ) {
        // Using % here is a trick to prevent notices
        // It's safe, since if the lengths are different
        // $result is already non-0
        $result |= (ord($safe[$i % $safeLen]) ^ ord($user[$i]));
    }

    // They are only identical strings if $result is exactly 0...
    return $result === 0;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Break

    Break

    10 Aralık 2005
  • DJPixcell

    DJPixcell

    20 NİSAN 2007
  • LiquidMusick

    LiquidMusick

    23 Aralık 2010