NodeJS üzerinde Kimlik Doğrulama Güvenliği

OWASP Top 10 içerisinde de bulunan yetersiz kimlik doğrulama açığının NodeJS üzerinde nasıl engellenebileceğine biraz bakalım.

Kimlik doğrulama üzerinden yapılabilecek potansiyel saldırılar şu şekilde:

  • Zayıf parola içeren kullanıcıları brute-force ile ele geçirme
  • Veritabanından parola çalınması
  • Parola yönetiminde bulunabilecek buglar (parola sıfırlama ya da kurtarma sayfaları)
  • Kullanıcıların tarayıcılarından ya da ağ üzerinden sessionID’lerinin çalınması

Uygulama geliştirirken yukarıdaki tehlikelere yönelik dikkat edeceğimiz noktaları şu şekilde sıralayabiliriz;

Brute-force ile Saldırılar

Zamanı ve kaynağı olan bir saldırganın yapabileceği saldırılardan birisidir.

Bu tip saldırılardan korunmak için parola güvenliğini sağlamanız gerekiyor. Yapabilecekleriniz:

  • Güçlü bir parola politikası
  • Giriş denemelerini IP ya da kullanıcı bazlı kısıtlama
  • Birden fazla başarısız deneme sonucunda kullanıcı hesabını kilitleme
  • Başarısız girişleri detaylı bir şekilde loglama ve logların düzenli olarak incelenmesi
  • Güvenli bir parola kurtarma politikası
    • Eski parolayı isteyin
    • Gizli soru cevabı isteyin
    • Parolamı unuttum gibi parola kurtarma opsiyonlarının mevcut parolayı karşı tarafa vermediğinden emin olun

Rainbow Tables ile Saldırılar

Rainbow table, önceden hashleri hesaplanmış parolalar içeren büyük bir sözlüktür. Saldırganlar çaldıkları hash değerlerinin açık hallerine rainbow table yardımıyla ulaşabilir.

Nasıl önleriz? Parolaları tuzlayarak

var bcrypt = require('bcrypt');
var _bcrypt = (__password) => new Promise((resolve, reject)=>{
 bcrypt.genSalt(12, function(err, salt) {
 bcrypt.hash(__password, salt, function(err, hash) {
 resolve(hash)
 });
 });
})
var _password = '/F4ZL4g-uv3nl1*B1rP4r0l4()'
_bcrypt(_password).then( 
 (result)=> console.log(result)
)

Burada kullanılan bcrypt.gensalt() fonksiyonu async bir fonksiyondur çünkü bcrypt ile yapılan hashleme işlemi CPU’ya yük bindiren bir işlemdir. Sync bir fonksiyon event loopu meşgul ederek uygulamanızın başka bir iş yapamamasına sebep olur. (bcrypt ile alakalı daha fazlasını şuradan okuyabilirsiniz)

Oturum Çalma

Kullanıcıların hatırlanması için kullanılan oturum ID’leri saldırganların hedefi olabilir.

Güvenli oturum yönetimi implementasyonu nasıl olmalı?

HTTP stateless olduğundan, HTTP istekleri sırasında kullanıcı verilerini bir şekilde tutmamız gerekiyor. Çerezler de burada devreye giriyor. Fakat; Cross-site scripting veya network snifferlar aracılığıyla çalınan oturum çerezleri ile kullanıcıların oturumu saldırganlar tarafından ele geçiriliyor.

NPM üzerindeki express-session modülü, bize güvenli bir oturum yönetimi sağlamakta. Oturum yönetimi için kullanabileceğimiz bazı ipuçları:

  • Oturum verilerini kullanıcı tarafında göstermeyin, çerezde sadece SID olsun
  • URL parametresi olarak oturumla alakalı her hangi bir şey bulunmasın
  • Production sunucularında oturum verisi saklamayın
  • httpOnly bayrağı ile çerezleri XSS tabanlı saldırılardan koruyun
  • secure bayrağı ile çerezleri sadece HTTPS üzerinden yollayın
  • Kullanıcı oturumunu kapattığında oturumun yok edildiğinden emin olun
var session = require('express-session');
app.use(session({
    resave: false,
    saveUninitialized: true,
    secret: 'COKSECRET',
    cookie: {
        httpOnly: true,
        secure: true,
        maxAge: 1 * 60 * 1000
    }
}));