PHP Oturum Güvenliği


125

PHP ile sorumlu oturum güvenliğini sürdürmek için bazı yönergeler nelerdir? İnternetin her yerinde bilgi var ve hepsinin tek bir yere konmasının zamanı geldi!

Yanıtlar:


88

Oturumunuzu güvende tutmak için yapmanız gereken birkaç şey var:

  1. Kullanıcıların kimliğini doğrularken veya hassas işlemler gerçekleştirirken SSL kullanın.
  2. Güvenlik seviyesi her değiştiğinde (oturum açmak gibi) oturum kimliğini yeniden oluşturun. Hatta dilerseniz her istekte oturum kimliğini yeniden oluşturabilirsiniz.
  3. Seanslar zaman aşımına uğrar
  4. Register globals kullanma
  5. Kimlik doğrulama ayrıntılarını sunucuda saklayın. Yani, çerezde kullanıcı adı gibi ayrıntıları göndermeyin.
  6. Kontrol edin $_SERVER['HTTP_USER_AGENT']. Bu, oturum kaçırmaya küçük bir engel ekler. Ayrıca IP adresini de kontrol edebilirsiniz. Ancak bu, birden fazla internet bağlantısında yük dengeleme vb.Nedeniyle değişen IP adresi olan kullanıcılar için sorunlara neden olur (buradaki ortamımızda durum budur).
  7. Dosya sistemindeki oturumlara erişimi kilitleyin veya özel oturum işlemeyi kullanın
  8. Hassas işlemler için, oturum açmış kullanıcıların kimlik doğrulama ayrıntılarını tekrar sağlamalarını zorunlu kılmayı düşünün.

15
Şifrelenmiş ve şifrelenmemiş trafik için ayrı oturumlarınız olmadıkça, SSL'yi yalnızca bazı işlemler için kullanmak yeterli değildir. HTTPS ve HTTP üzerinden tek oturum kullanırsanız, saldırgan bunu HTTPS olmayan ilk istekte çalar.
Kornel

6
-1 kullanıcı aracısı yanıltmak için önemsizdir. Açıkladığınız şey kodu israf eder ve bir güvenlik sistemi değildir.
kale

24
@ The Rook, önemsiz bir engel olabilir (saldırgan, kendi sitesini kullanarak bir kurbanın kullanıcı aracısını ele geçirebilir) ve belirsizlik yoluyla güvenliğe güvenir, ancak yine de ekstra bir engeldir. User-Agent HTTP, oturum kullanımı sırasında değişecek olsaydı, son derece şüpheli ve büyük olasılıkla bir saldırı olurdu. Tek başına kullanabileceğini hiç söylemedim. Diğer tekniklerle birleştirirseniz çok daha güvenli bir siteniz olur.
grom

5
@grom Kapınıza bir parça viski bandı koyarak insanların içeri girmesini önleyeceğini söylemeye benziyor.
kale

8
Kullanıcı aracısını kontrol ediyorsanız, uyumluluk moduna geçtiklerinde IE8 kullanıcılarından gelen tüm istekleri engellersiniz. Bu sorunu kendi kodumda izlediğim eğlenceye bakın: serverfault.com/questions/200018/http-302-problem-on-ie7 . Kullanıcı aracısını kontrol ettim, çünkü başkalarının da söylediği gibi yanıltmak çok önemsiz bir şey.
bestattendance


11

İki (veya daha fazla) sentim:

  • Kimseye güvenme
  • Filtre girişi, çıkış çıkışı (çerez, oturum verileri sizin de girdinizdir)
  • (İyi oluşturulmuş HTML tutmak bakmak XSS kaçının PHPTAL veya HTMLPurifier )
  • Derinlemesine savunma
  • Verileri ifşa etmeyin

Bu konuyla ilgili küçük ama güzel bir kitap var: Chris Shiflett tarafından yazılan Temel PHP Güvenliği .

Temel PHP Güvenliği http://shiflett.org/images/essential-php-security-small.png

Kitabın ana sayfasında bazı ilginç kod örnekleri ve örnek bölümler bulacaksınız.

Yukarıda belirtilen tekniği (IP ve KullanıcıAracısı) burada açıklanan tekniği kullanabilirsiniz: Kimlik hırsızlığı nasıl önlenir


XSS önleme için +1. Bu olmadan CSRF'ye karşı koruma sağlamak imkansızdır ve bu nedenle birisi oturum kimliğini bile almadan oturumu "sürdürebilir".
Kornel

11

Bence en büyük problemlerden biri (PHP 6'da ele alınan) register_globals. Şu anda kaçınmak register_globalsiçin kullanılan standart yöntemlerden biri $_REQUEST, $_GETveya $_POSTdizilerini kullanmaktır.

Bunu yapmanın "doğru" yolu (5.2'den itibaren, biraz hatalı olmasına rağmen, ancak 6 itibariyle kararlı, yakında gelecek olan) filtrelerden geçer .

Yani bunun yerine:

$username = $_POST["username"];

yaparsın:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

hatta sadece:

$username = filter_input(INPUT_POST, 'username');

2
Bunun soruyla hiçbir ilgisi yok.
The Pixel Developer

5
Gerçekten mi? Öyleyse neden kabul edilen cevapta register globals'ı kullanmamaları belirtiyorlar? Teknik olarak "oturum" nesnesinin bir parçası olmasa bile, çoğu sıradan geliştirici söz konusu olduğunda, küreselleri kaydetme ve değişken işleme biçimi, "oturumlar" şemsiyesi altına girmez mi?
cmcculloh

9
Katılıyorum, bu soruya tam olarak cevap vermiyor, ancak kesinlikle sorunun cevabının BİR PARÇASI. Yine, bu, kabul edilen yanıtta bir madde işareti ortaya çıkarır: "Register globals" kullanma. Bu, bunun yerine ne yapılacağını söyler.
cmcculloh


5

IP adresini kullanmak, deneyimlerime göre gerçekten en iyi fikir değil. Örneğin; Ofisimde yüke bağlı olarak kullanılan iki IP adresi var ve IP adreslerini kullanırken sürekli sorunlarla karşılaşıyoruz.

Bunun yerine, oturumları sunucularımdaki etki alanları için ayrı bir veritabanında depolamayı seçtim. Bu şekilde dosya sistemindeki hiç kimse bu oturum bilgilerine erişemez. Bu 3.0 öncesi phpBB ile gerçekten yardımcı oldu (o zamandan beri bunu düzelttiler) ama yine de iyi bir fikir olduğunu düşünüyorum.


3

Bu oldukça önemsiz ve açıktır, ancak her kullanımdan sonra session_destroy yaptığınızdan emin olun . Kullanıcı açıkça oturumu kapatmazsa bunu uygulamak zor olabilir, bu nedenle bunu yapmak için bir zamanlayıcı ayarlanabilir.

İşte setTimer () ve clearTimer () hakkında iyi bir öğretici .


3

PHP oturumları ve güvenliği ile ilgili temel sorun (oturum kaçırmanın yanı sıra) hangi ortamda olduğunuzla ilgilidir. Varsayılan olarak PHP, oturum verilerini işletim sisteminin geçici dizinindeki bir dosyada depolar. Herhangi bir özel düşünce veya planlama olmaksızın, bu tüm dünyada okunabilir bir dizindir, bu nedenle tüm oturum bilgileriniz sunucuya erişimi olan herkes için halka açıktır.

Oturumları birden çok sunucu üzerinden sürdürmeye gelince. Bu noktada PHP'yi, sağladığınız işlevleri CRUD'a çağırdığı (oluşturma, okuma, güncelleme, silme) kullanıcı tarafından yönetilen oturumlara geçirmek daha iyi olacaktır. Bu noktada, tüm uygulama sunucularının verilere erişebilmesi için oturum bilgilerini bir veritabanında veya memcache benzeri bir çözümde depolayabilirsiniz.

Paylaşılan bir sunucu üzerindeyseniz, kendi oturumlarınızı saklamak da avantajlı olabilir, çünkü onu veri tabanında saklamanıza izin verir, bu da çoğu zaman dosya sistemi üzerinde daha fazla kontrole sahip olursunuz.


3

Seanslarımı böyle ayarladım-

giriş sayfasında:

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);

(yapılandırma sayfasında tanımlanan ifade)

daha sonra sitenin geri kalan kısmındaki başlıkta:

session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
    header('Location: http://website login page/');
    exit();     
}

3

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache başlık ekle:

X-XSS-Protection    1

httpd.conf -> <FilesMatch "\. (php | phtml | aspx | htm | html) $"> Üstbilgi kümesi X-XSS-Protection "1" </FilesMatch>
user956584

Bunun X-XSS-Protectiongerçekten yararlı olmadığının farkında olun . Aslında, koruma algoritmasının kendisi aslında kötüye kullanılabilir, bu da onu eskisinden daha kötü hale getirir.
Pacerier

2

Değişip değişmediklerini görmek için hem IP'yi hem de Kullanıcı Aracısını kontrol ederdim

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}

5
Kullanıcı yük dengeli proxy çiftliğinin gerisindeyse IP yasal olarak değişebilir.
Kornel

2
Ve user_agent, bir kullanıcı tarayıcısını her yükselttiğinde değişebilir.
scotts

3
@scotts IP kısmına katılıyorum, ancak tarayıcı yükseltmesi için, oturum açtıklarında oturumu ayarlarsınız, böylece yeniden oturum açtıklarında yeni bir oturum oluşturmadan tarayıcıyı nasıl yükselteceklerini görmüyorum.
JasonDavis

User_agent'in IE8'de uyumlu mod arasında geçiş yaparken de değişebileceğine inanıyorum. Sahte olması da çok kolaydır.

Evet, peki ya statik IP eq GSM'ye sahip olan ve her yarım saatte bir değiştirilen kullanıcılar? Yani, Oturum + ana bilgisayar adında depolanan IP, NE ZAMAN IP! = UZAKTAN_ADDR ana bilgisayarı kontrol edin ve ana bilgisayar eq. 12.12.12.holand.nl-> holand.nl == true olduğunda. Ancak bazı ana bilgisayarların IP tabanlı ana bilgisayar adı vardı O zaman 88.99.XX.XX maskesini karşılaştırmanız gerekir
user956584

2

Session_set_save_handler () kullanıyorsanız , kendi oturum işleyicinizi ayarlayabilirsiniz. Örneğin, oturumlarınızı veri tabanında saklayabilirsiniz. Veritabanı oturumu işleyicisi örnekleri için php.net yorumlarına bakın.

Birden fazla sunucunuz varsa DB oturumları da iyidir, aksi takdirde dosya tabanlı oturumlar kullanıyorsanız, her web sunucusunun oturumları okumak / yazmak için aynı dosya sistemine erişimi olduğundan emin olmanız gerekir.


2

Oturum verilerinin güvende olduğundan emin olmanız gerekir. Php.ini dosyanıza bakarak veya phpinfo () kullanarak oturum ayarlarınızı bulabilirsiniz. _session.save_path_, nereye kaydedildiklerini size söyler.

Klasörün ve üstlerinin iznini kontrol edin. Herkese açık olmamalı (/ tmp) veya paylaşılan sunucunuzdaki diğer web siteleri tarafından erişilebilir olmamalıdır.

Hala php oturumunu kullanmak istediğinizi varsayarsak, _session.save_path_ değiştirerek php'yi başka bir klasörü kullanacak şekilde ayarlayabilir veya _session.save_handler_'ı değiştirerek verileri veritabanına kaydedebilirsiniz.

Sitenizin kök klasöründe bir .htaccess dosyasında, php.ini _session.save_path_ ayarlamak mümkün (bazı sağlayıcılar buna izin) ya da apache + mod_php için olabilir: php_value session.save_path "/home/example.com/html/session". Ayrıca _session_save_path () _ ile çalışma zamanında da ayarlayabilirsiniz.

Kontrol Chris Shiflett en öğretici veya Zend_Session_SaveHandler_DbTable seti ve alternatif Oturum kayıt için.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.