Tamam, iki ayrı ama ilişkili sorun var ve her biri farklı şekilde ele alınıyor.
Oturum Sabitleme
Bu, bir saldırganın bir kullanıcı için bir oturumun oturum tanımlayıcısını açıkça belirlediği yerdir. Tipik olarak PHP'de bu onlara beğeni URL'si verilerek yapılır http://www.example.com/index...?session_name=sessionid
. Saldırgan url'yi istemciye verdiğinde, saldırı, oturum kaçırma saldırısıyla aynıdır.
Oturumu sabitlemenin birkaç yolu vardır (hepsini yapın):
Set session.use_trans_sid = 0
sizin de php.ini
dosyaya. Bu, PHP'ye tanımlayıcıyı URL'ye dahil etmemesini ve tanımlayıcılar için URL'yi okumamasını söyleyecektir.
Set session.use_only_cookies = 1
sizin de php.ini
dosyaya. Bu, PHP'ye oturum tanımlayıcıları olan URL'leri asla kullanmamasını söyleyecektir.
Oturumun durumu her değiştiğinde oturum kimliğini yeniden oluşturun. Bu, aşağıdakilerden herhangi biri anlamına gelir:
- Kullanıcı doğrulama
- Hassas bilgilerin oturumda saklanması
- Seansla ilgili herhangi bir şeyi değiştirmek
- vb...
Oturum çalma
Burası, bir saldırganın bir oturum tanımlayıcısını ele geçirdiği ve o kullanıcı gibi istekler gönderebildiği yerdir. Bu, saldırganın tanımlayıcıya sahip olduğu için, sunucu açısından geçerli kullanıcıdan ayırt edilemez olduğu anlamına gelir.
Oturum kaçırmayı doğrudan önleyemezsiniz. Bununla birlikte, kullanımı çok zor ve daha zor hale getirmek için adımlar atabilirsiniz.
Güçlü bir oturum karma tanımlayıcısı kullanın: session.hash_function
içinde php.ini
. PHP <5.3 session.hash_function = 1
ise SHA1 için ayarlayın . PHP> = 5.3 ise, session.hash_function = sha256
veya olarak ayarlayın session.hash_function = sha512
.
Güçlü bir hash gönderin: session.hash_bits_per_character
in php.ini
. Bunu olarak ayarlayın session.hash_bits_per_character = 5
. Bu, kırılmasını daha da zorlaştırmasa da, saldırganın oturum tanımlayıcısını tahmin etmeye çalışması bir fark yaratır. Kimlik daha kısa olacaktır, ancak daha fazla karakter kullanır.
İle ek bir entropi ayarlayın session.entropy_file
ve session.entropy_length
sizin de php.ini
dosyaya. İlkini olarak session.entropy_file = /dev/urandom
ve ikincisini entropi dosyasından okunacak bayt sayısına ayarlayın, örneğin session.entropy_length = 256
.
Varsayılan PHPSESSID'den oturumun adını değiştirin. Bu, aramadan session_name()
önce ilk parametre olarak kendi tanımlayıcı adınızla çağrı yaparak gerçekleştirilir session_start
.
Eğer gerçekten paranoyak iseniz, oturum adını da döndürebilirsiniz, ancak bunu değiştirirseniz (örneğin, saate bağlı hale getirirseniz) tüm oturumların otomatik olarak geçersiz kılınacağına dikkat edin. Ancak kullanım durumunuza bağlı olarak, bir seçenek olabilir ...
Oturum tanımlayıcınızı sık sık değiştirin. Bunu her istekte yapmazdım ( gerçekten o güvenlik seviyesine ihtiyacınız yoksa ), ancak rastgele bir aralıkta. Bunu sık sık değiştirmek istersiniz, çünkü bir saldırgan bir oturumu ele geçirirse, onu çok uzun süre kullanmasını istemezsiniz.
Kullanıcı aracısını$_SERVER['HTTP_USER_AGENT']
oturuma dahil edin . Temel olarak, oturum başladığında, bunu gibi bir yerde saklayın $_SESSION['user_agent']
. Ardından, sonraki her istekte eşleşip eşleşmediğini kontrol edin. Bunun sahte olabileceğini unutmayın, bu yüzden% 100 güvenilir değildir, ancak olmamasından daha iyidir.
Dahil dan kullanıcının IP adresini$_SERVER['REMOTE_ADDR']
oturumunda. Temel olarak, oturum başladığında, bunu gibi bir yerde saklayın $_SESSION['remote_ip']
. Bu, kullanıcıları için birden çok IP adresi kullanan bazı ISS'ler için sorunlu olabilir (eskiden AOL gibi). Ancak kullanırsanız çok daha güvenli olacaktır. Bir saldırganın IP adresini kandırmasının tek yolu, gerçek kullanıcı ile sizin aranızda bir noktada ağı tehlikeye atmaktır. Ve eğer ağı tehlikeye atarlarsa, bir korsanlıktan çok daha kötüsünü yapabilirler (MITM saldırıları vb.).
Oturuma ve tarayıcı tarafında sık sık artırıp karşılaştırdığınız bir belirteç ekleyin. Temel olarak, her istek $_SESSION['counter']++
için sunucu tarafında yapın. Ayrıca aynı şeyi yapmak için tarayıcı tarafında JS'de bir şeyler yapın (yerel bir depolama kullanarak). Ardından, bir istek gönderdiğinizde, yalnızca bir belirteç alın ve nonce'nin sunucuda aynı olduğunu doğrulayın. Bunu yaparak, saldırganın tam sayacı olmayacağı için ele geçirilmiş bir oturumu tespit edebilmelisiniz veya eğer varsa, aynı sayıyı ileten ve birinin sahte olduğunu söyleyebilecek 2 sisteminiz olacaktır. Bu, tüm uygulamalarda işe yaramayacaktır, ancak sorunla mücadele etmenin bir yoludur.
İkisine bir not
Oturumu Sabitleme ile Ele Geçirme arasındaki fark, yalnızca oturum tanımlayıcının güvenliğinin nasıl ihlal edildiğiyle ilgilidir. Sabitlemede, tanımlayıcı saldırganın önceden bildiği bir değere ayarlanır. Ele geçirme işleminde ya tahmin edilir ya da kullanıcıdan çalınır. Aksi takdirde, tanımlayıcı tehlikeye atıldığında ikisinin etkileri aynıdır.
Oturum Kimliği Yenileme
session_regenerate_id
Eski oturumu kullanarak oturum tanımlayıcısını her yeniden oluşturduğunuzda silinmelidir. Bu, çekirdek oturum işleyicisinde şeffaf bir şekilde gerçekleşir. Ancak, kullanansession_set_save_handler()
bazı özel oturum işleyicileri bunu yapmaz ve eski oturum tanımlayıcılarına saldırmaya açıktır. Özel bir oturum işleyicisi kullanıyorsanız, açtığınız tanımlayıcıyı takip ettiğinizden ve kaydettiğiniz tanımlayıcıyla aynı değilse, eskisi üzerindeki tanımlayıcıyı açıkça sildiğinizden (veya değiştirdiğinizden) emin olun.
Varsayılan oturum işleyiciyi kullanarak, sadece aramakta sorun yok session_regenerate_id(true)
. Bu sizin için eski oturum bilgilerini kaldıracaktır. Eski kimlik artık geçerli değildir ve saldırgan (veya bu konuda başka biri) kullanmaya çalışırsa yeni bir oturum açılmasına neden olur. Yine de özel oturum işleyicilerine dikkat edin ....
Bir Oturumu Yıkmak
Bir oturumu yok edecekseniz (örneğin oturumu kapattığınızda), tamamen yok ettiğinizden emin olun. Bu, çerezin ayarının kaldırılmasını içerir. Kullanarak session_destroy
:
function destroySession() {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
session_destroy();
}