PHP giriş komut dosyasında hangi en iyi yöntemler kullanılmalıdır?


27

Müşterilerimin web siteleri için giriş komut dosyalarımı daha güvenli hale getirmek için yeniden yazmak istiyorum. Bunun için hangi en iyi uygulamaları uygulayabileceğimi bilmek istiyorum. Parola korumalı kontrol panelleri bolluk içindedir, ancak çok azının kod yazma, hız ve güvenlik açısından en iyi uygulamaları etkilediği görülüyor.

PHP ve bir MYSQL veritabanı kullanacağım.

Eskiden md5 kullandım, ancak sha256 veya sha512'nin daha iyi olacağını gördüm (güvenli karma ve tuz ile birlikte).

Bazı oturum açma komut dosyaları ip adresini oturum boyunca ve hatta kullanıcı aracısını kaydeder, ancak proxy sunucularla uyumlu olmadığından kaçınmak istiyorum.

Ayrıca PHP 5'teki oturumları kullanmada en iyi uygulamanın biraz gerisinde kaldım (en son okuduğumda PHP 4 idi), bu nedenle bu konuda en iyi uygulamaların bazıları yardımcı olacaktır.

Teşekkürler.


1
Komut dosyanızı kod görünümü üzerinde atın.
Chris,

@Chris CodeReview kod netliği ve benzeri ile yardımcı olur. Kesinlikle güvenlik için onlara gitmemelisin. Bir şey olursa, hemen hemen her zaman size "kendi yuvarlamanızı" hatırlatmayacağını hatırlatırlar; bu temelde SE'deki herhangi bir programlama topluluğuna gireceği cevap aynıdır.
Alternatex

Yanıtlar:


21

En iyi düşünce tekerleği yeniden icat etmemek. Ancak, PHP dünyasında zaten bunu yapan yüksek kaliteli bir bileşen bulmak zor olabilir (çerçevelerin bu tür şeyleri uyguladığından ve uygulamalarının zaten test edilmiş, sağlam, kod gözden geçirilmiş vb. Olduğundan emin olabilirim). )

Bazı nedenlerden dolayı, bir çerçeveyi kullanamazsanız, işte bazı öneriler:

Güvenlikle ilgili öneriler

  • Mümkünse PBKDF2 veya Bcrypt kullanın . Bunun için yapıldı.

    Gerekçe: Her iki algoritma da karma işlemi isteğe bağlı olarak yavaşlatabilir; bu, şifreleri toplamarken tam olarak istediğiniz şeydir (daha hızlı alternatifler daha kolay kaba kuvvet anlamına gelir). İdeal olarak, parametreleri, aynı donanımda işlem zaman içinde daha yavaş ve daha yavaş olurken yeni, daha hızlı donanım piyasaya sürülecek şekilde ayarlamanız gerekir.

  • Yapamazsanız , en azından MD5 / SHA1 kullanmayın. Asla. Unut gitsin . Örneğin bunun yerine SHA512 kullanın. Ayrıca tuz kullanın.

    Gerekçe: MD5 ve SHA1 çok hızlı. Saldırganın karmaları içeren veritabanınıza erişimi varsa ve (özellikle de) güçlü bir makineye sahipse, bir parolanın kaba şekilde zorlanması hızlı ve kolaydır. Tuz yoksa, saldırganın gerçek parola artışını bulma olasılığı (parola başka bir yerde tekrar kullanılırsa ek zarar verebilir).

  • PHP 5.5.0 ve sonrasında, kullanmak password_hashve password_verify.

    Gerekçe: çerçeve tarafından sağlanan bir işlevi çağırmak kolaydır, bu nedenle hata yapma riski azalır. Bu iki işlevle, karma gibi farklı parametreler hakkında düşünmeniz gerekmez. İlk işlev , daha sonra veritabanında depolanabilen tek bir dize döndürür . İkinci işlev bu dizgiyi parola doğrulaması için kullanır.

  • Kendinizi kaba kuvvetten koruyun . Kullanıcı 0.01 saniye önce başka bir yanlış şifre daha gönderdiğinde yanlış bir şifre girerse, bunu engellemek için iyi bir nedendir. İnsanlar hızlı yazabiliyor olsalar da, muhtemelen o kadar hızlı olamazlar .

    Diğer bir koruma, saatlik arıza limiti belirlemek olacaktır. Kullanıcı bir saatte 3600 yanlış şifre, saniyede 1 şifre girerse, bunun meşru bir kullanıcı olduğuna inanmak zordur.

    Gerekçe: Şifreleriniz güvensiz bir şekilde şifrelenmişse kaba kuvvet çok etkili olabilir. Parolalar güvenli bir şekilde saklanırsa, kaba güç hala sunucunuzun kaynaklarını ve ağ bant genişliğini boşa harcar ve meşru kullanıcılar için daha düşük performansa neden olur. Kaba kuvvet saptamanın geliştirilmesi ve düzeltilmesi kolay değildir, ancak küçük sistemler dışında, tamamen buna değer.

  • Kullanıcılarınızdan her dört haftada bir şifrelerini değiştirmelerini istemeyin. Bu son derece can sıkıcı ve güvenliği azaltır çünkü post-it tabanlı güvenliği teşvik ediyor.

    Gerekçe: Her değiştirmeye şifreleri zorlayarak fikri n haftalar kaba kuvvet sistemi korur yanlıştır. Kaba kuvvet saldırıları genellikle saniyeler, dakikalar, saatler veya günler içinde başarılı olur; bu da aylık parola değişikliklerini alakasız hale getirir. Öte yandan, kullanıcılar şifreleri hatırlamakta kötüdürler. Dahası, onları değiştirmek zorunda kalırlarsa ya çok basit şifreler kullanmaya çalışırlar ya da şifrelerini post-it üzerine not ederler.

  • Her zaman her şeyi denetleyin. Girişleri saklayın, ancak şifreleri hiçbir zaman denetim günlüğünde saklamayın. Denetim günlüğünün değiştirilemediğinden emin olun (örneğin, sonunda veri ekleyebilir ancak mevcut verileri değiştiremezsiniz). Denetim günlüklerinin düzenli yedeklemeye tabi olduğundan emin olun. İdeal olarak, günlükler çok kısıtlayıcı erişime sahip özel bir sunucuda depolanmalıdır: eğer başka bir sunucu saldırıya uğrarsa, saldırgan varlığını (ve saldırı sırasında atılan yolu) gizlemek için günlükleri silemez.

  • Çerezlerde kullanıcı kimlik bilgilerini hatırlamayın, kullanıcı bunu yapmasını istemedikçe (“Beni hatırla” onay kutusunun, insan hatasını önlemek için varsayılan olarak işaretlenmemiş olması gerekir).

Kullanım kolaylığı önerileri

  • Çoğu tarayıcı zaten bu özellik olsa bile , kullanıcının isterse şifreyi hatırlamasını sağlayın .
  • Kullanıcı adını ve şifreyi sormak yerine , kullanıcı adında zaten bir adda görüntülenen, bazen yalnızca şifre istendiğinde , Google yaklaşımını kullanmayın <span/>. Tarayıcılar bu durumda şifre alanını dolduramaz (en azından Firefox bunu yapamaz), bu nedenle oturum kapatmaya, ardından tarayıcı tarafından doldurulmuş normal bir formla oturum açmaya zorlar.
  • Oturum açmak için JavaScript etkin açılır pencereleri kullanmayın . Tarayıcıların parola hatırlama özelliklerini kırar (ve her durumda berbattır).
  • Kullanıcının kullanıcı adını veya posta adresini girmesine izin verin . Kayıt yaptırdığımda, bazen girmek istediğim kullanıcı adı zaten alınmış, bu yüzden yeni bir tane icat etmeliyim. İki saat içinde bu ismi unutma şansım var.
  • Her zaman oturum açma formunun yanında bulunan "Şifremi unuttum" özelliğinin bağlantısını daima saklayın . Yalnızca kullanıcı oturum açamadığında göstermeyin: şifresini hiç hatırlamayan kullanıcı, "Şifremi unuttum" bağlantısını görmek için yanlış bir mesaj göndermesi gerektiğini bilmiyor.
  • Post-it tarafından güvenlik kullanmayın .
  • Bunu zayıflatmak için şifre ile ilgili aptal kurallar icat etmeyin . Örnek: "Parolanız küçük harfle başlamalıdır."; "Şifreniz boşluk içeremez."

Bcrypt ile karşılaşmayın. Bunu önermek için nedeniniz? Neden md5 / sha1 değil? Önerilerin kalanı için teşekkürler!
baritoneuk

Sebep basittir: bcryptyüksek nitelikli insanlar tarafından yapılır. Aynı zamanda test edildi, gözden geçirildi, vb. Bu yüzden aynı şeyi kendiniz uygulamak için hiçbir neden yoktur. Web siteniz için kendi şifreleme algoritmanızı oluşturmak gibi bir şey. * "Neden md5 / sha1 değil?": Bakınız örneğin en.wikipedia.org/wiki/MD5#Security
Arseni Mourzenko

5
bcrypt yavaştır ve bahsedildiği gibi profesyoneller tarafından uygulanır. md5, tamamen aynı şey olmayan bir şifreleme değil, karma algoritmadır. Bir dosyanın hızlı bir şekilde yayınlanması iyidir, burada md5 kullanılacaktır ... bir şifrenin çok hızlı olması gerekmez, bcrypt burada yardımcı olabilir. Sebep bunun crypt algoritması "slow" olduğunda kaba kuvvetin daha zor hale geldiğini söylüyorum.
Chris,

2
@baritoneuk: minimum serin. Ancak , maksimum uzunluk, alfanümerik olmayan karakter vb. Gibi kısıtlamaları olan kaç tane siteye girdiğimi hesaplayamıyorum . Yine de, eğer şifrenizi yine de şifreleyecekseniz - bu beni rahatsız etmemelerini sağlıyor , sadece veritabanında depoya koyuyorlar.
Carson63000

1
@Brian Ortiz: her zaman değil. Bazen bir sınır koymak iyi bir fikirdir. Yapmazsanız, başvurunuzun herhangi bir uzunlukta çalışıp çalışmadığını test ediyor musunuz? Nasıl? Test etmezseniz, çalıştığından nasıl emin olabilirsiniz? Bunun yerine, 100 gibi makul bir değere bir sınır belirlerken, 100 karakterlik bir şifreyi kolayca test edebilirsiniz.
Arseni Mourzenko

6
  1. Siteniz HTTPS kullanmalı. Hiçbir zaman bir giriş sayfası sunmamalı veya şifrelenmemiş bir bağlantıdan girişleri kabul etmemelisiniz.
  2. Çerezleriniz sadece HTTP ile sınırlı olmalı ve HTTPS kullanıyorsanız güvenli bağlantılarla kısıtlanmalıdır.
  3. Giriş işlemi 2 saniyeden az sürmemelidir (2 saniyenin çok uzun olduğunu düşünüyorsanız 1). Şifreleri saklarken ve doğrularken güvenli bir karma kullanın ve tahmin edilmesi daha zor bir tuz kullanın. bcryptMümkünse kullanın . Aksi takdirde, başka tür yinelenmiş karma kullanın.
  4. Hiçbir zaman hiç gibi işlevleri kullanarak gerektiren herhangi bir şekilde veritabanı sorgularını oluşturmak mysql_real_escape_string. Sorgunuzu oluşturmak için asla dize birleştirme kullanmayın. Hazırlanmış, parametreli sorgulamalar kullanın. Hepsi değilse de, PHP için DB sürücüleri bunu desteklemektedir. Eğer nasıl yapılacağını bilmiyorsanız, nasıl biraz zaman öğrenme harcamak prepare, bindve executekullanan olursa olsun DB kullandığınız. Bu var sadece SQL enjeksiyonu karşı kendinizi korumak için emin bir yol. PDO bunu destekliyor.
  5. Kullanmasını sağlayın değil kendi e-postası için kullandığınız şifreyi kullanmayın. Onlara, sitenizin tehlikeye atılması ve her iki yerde de aynı şifreyi kullanmaları durumunda birinin e-postalarını ele geçirebileceğini hatırlatın.

Ortak WiFi ağları üzerinden giderek daha fazla trafik olduğundan HTTPS için +1. Ancak 3: 2 saniye, kullanıcıların bakış açısından çok uzun. 0.5 s. özellikle başka kaba kuvvet uygulama teknikleri kullanılıyorsa gayet iyi.
Arseni Mourzenko

# 4 numaralı noktada kafam karıştı. Mysql_real_escape_string ile kaçan verilerin kurallarından nasıl kaçarsınız? Gönderilen tüm veriler güvenilmemeli ve buna göre filtrelenmemelidir.
chrisw

@ chris: Evet, tüm kullanıcı girişi kötü niyetliymiş gibi kullanılmalıdır. Ancak, parametreli sorguları kullandığınızda, hiçbiri, SQL enjeksiyonunu durdurmanın en iyi yoludur . Hazırlanmış ve parametreli hale getirilmiş sorguları kullanmıyorsanız, SQL enjeksiyonuna açıksınızdır. mysql_real_escape_stringyanlış bir güvenliktir - bu bir garanti değildir. Parametreli sorgular şunlardır.
greyfade

Biraz daha okuduktan sonra şimdi katılıyorum. İşlev: mysql_real_escape_string genellikle çoğunlukla güvenlidir, BÜYÜK bir sorumluluk olarak düşünmüyorum, ancak hazırlanan ifadelerin kullanılmasının çok daha etkili olduğunu görebiliyorum.
chrisw

1
PDO'yu kullanabilirsiniz.
Felix G

1

Tuzlu, tek yönlü bir karma kullanın (tercihen http://au2.php.net/manual/en/function.hash.php kullanarak SHA512 ) ... bu şekilde, eğer biri sizin veritabanınızı hack ederse, tuzu bilseler bile Parolaları çıkaramazlar (SHA512 için çok uzun olan bir gökkuşağı masası olmadan).

HTTPS kullanın.

Kullanıcı adı / şifre onaylarını, e-posta yoluyla, kaydolduktan sonra kullanıcıya geri göndermeyin.

'Beni hatırla' için çerezlere izin verirseniz - yönetim ve profil düzenleme işlevlerine erişmek için fazladan bir giriş yapın.

Bir kullanıcı yanlış bir şifre alırsa, şifreyi yanlış aldıklarını söyleme (her zaman 'kullanıcı adı veya şifreyi yanlış söylediklerini söyleyin) - bu şekilde, geçerli kullanıcı adlarının ne olduğu hakkında daha az ipucu.

Ekran ismine karşı giriş yapmayı deneyin ve uygulayın - bu şekilde, daha az kullanıcı giriş bilgilerini kullanıcı listelerinde gösterecektir.


Düz e-postayla e-posta göndermeme konusundaki bit ile tamamen aynı fikirdesiniz. Web sitelerinin bunu yaptığı zamanları kaybettim. Tüm siteler için 1 şifreniz varsa (ki neyse ki ben kullanmam), o zaman potansiyel olarak tüm web siteleri tehlikeye atılır. Bu tür web siteleri muhtemelen şifreleri düz metin olarak da saklar.
baritoneuk

1
  • Asla MD5 veya SHA1 karma algoritmaları kullanmayın. Her zaman SHA512 gibi yeni olanlara bağlı kalın
  • Her zaman güçlü bir rastgele oluşturulmuş tuz kullanın
  • Kullanıcılarınıza şifrelerini, "Şifremi Unuttum" durumunda bile asla e-postayla göndermeyin.
  • Asla mysql_ * fonksiyonlarını kullanmayın. Uzun süredir amortismana tabi tutuluyorlar. PDO'ya yapış
  • Şifreleri asla oturumlarda veya çerezlerde saklamayın

0

İşte size bir tavsiye: hırsızlığı önlemek için tanımlama bilgilerinize JS ile erişilemediğinden emin olun, bkz. Tanımlama Bilgilerini Koruma: HttpOnly , Jeff Atwood

... Akıllı yapı sayesinde hatalı biçimlendirilmiş URL, dezenfektanı gıcırtıyor. Son kod, tarayıcıda görüntülendiğinde, bu uzak sunucudan bir komut dosyası yükler ve yürütür.

... bu komut dosyası tarafından enjekte edilen kullanıcı profili sayfasını kim yüklerse, tarayıcı tanımlama bilgilerini istemeden kötü bir uzak sunucuya iletmiştir!

Daha önce belirlediğimiz gibi, birileri belirli bir web sitesi için tarayıcı çerezlerine sahip olduğunda, esasen orada kimliğiniz için krallığın anahtarlarına sahip olurlar ...

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.