NestJS + Next.js Güvenlik Sertleştirmesi: Üretim Yapılandırması
Bir NestJS arka ucu ve Next.js ön ucu için üretime gönderdiğimiz somut güvenlik yapılandırması — helmet varsayılanları, CSP, hız sınırları, HSTS ve üç ekibin tekrarladığını gördüğümüz bir yetkilendirme hatası.
NestJS ve Next.js'teki varsayılan güvenlik, çoğu eğitimin kabul ettiğinden daha incedir. Helmet, 2026'da B2B alıcıları için yeterli olmayan sağduyulu varsayılanlarla gönderilir, hız sınırlayıcı birden çok kopyalı bir dağıtımda dürüst olmak için Redis destekli depolama gerektirir ve herkesin kullanıma hazır olarak kullandığı yetkilendirme muhafızı kalıbının üç farklı kod tabanında üretime gönderdiğini gördüğümüz ince bir hatası vardır. Bu yazı, gönderdiğimiz yapılandırmadır.
Arka uç: NestJS sertleştirme
Helmet, ama varsayılanlar değil
Varsayılan helmet() çağrısı küçük bir başlık seti ayarlar, ancak varsayılanlar B2B kitlesi için yeterince agresif değildir. Gönderdiğimiz yapılandırma:
-
HSTS
maxAge: 63072000(2 yıl),includeSubDomains: true,preload: trueile. Daha kısa olan her şey, sertifikayı döndüreceğiniz ve sabitlenmiş istemcilerini bozacağınız alıcıya bir sinyaldir. -
frameguard
action: "deny"ile — sıkıDENY,SAMEORIGINdeğil. Uygulamamızda başka bir sitenin çerçevelemesini gerektiren hiçbir UI yok. -
referrerPolicy
policy: "strict-origin-when-cross-origin"ile — çapraz kaynak navigasyonunda çıplak kaynağı sızdırın, daha fazlasını değil. -
Content-Security-Policy sıkı bir
default-src 'self'ile, ardından onaylanmış görüntü/komut dosyası/bağlantı kaynaklarının açık bir listesi. CSP, derinlik savunması için tek en önemli başlıktır; bir güvenlik incelemesinden sonra değil, göndermeden önce ayarlayın.
Throttler, Redis destekli depolamayla
NestJS'in @nestjs/throttler paketi varsayılan olarak bellek içi depolamayla gönderilir. Bu, geliştirme ortamında iyidir ve üretimde güvensizdir: her kopyanın kendi sayacı vardır ve bir saldırgan, herhangi biri tetiklenmeden önce kopyalar × limit istek gönderebilir.
Düzeltme:
-
Sayacı kopyalar arasında Redis aracılığıyla paylaşmak için
@nest-lab/throttler-storage-redis'i bağlayın. -
Depolama URI'sini önbelleğiniz olarak aynı Redis'e ayarlayın. Kimlik doğrulama throttler'ı, uygulamanın geri kalanıyla darboğazı paylaşır, ancak bu doğrudur — kötüye kullanımın aslında yoğunlaştığı yer kimlik doğrulama yoludur.
Brute-force koruması, hız sınırından ayrı olarak
Hız sınırları "tek bir IP ne sıklıkta deneyebilir?" sorusuna cevap verir. Brute-force koruması, bir hesap 5 yanlış parola gördüğünde ne olur sorusuna cevap verir. İkisi de gereklidir. Brute-force katmanı:
-
Aynı hesapta art arda 5 başarısızlık → 15 dakikalık kilit, 429 veya 423 Locked döndürür.
-
Başarılı oturum açmada sayaç sıfırlanır.
-
Etkin olmayan hesaplar kilitlenmez. (Nedeni: bir saldırgan, meşru bir yöneticinin yeniden etkinleştirmesini önlemek için etkin olmayan bir hesabı kilitleyerek DdoS yapabilir.)
-
Zamanlama eşitlenir: bcrypt.compare, e-posta mevcut olmadığında bile kukla bir karma karşı çalışır, böylece yanıt süresi kullanıcı numaralandırmasını sızdırmaz.
Yetkilendirme muhafızı hatası
Üç farklı kod tabanında üç kez gördüğümüz hata:
// TEHLİKELİ — rolü istemcinin ayarlayabileceği bir başlıktan okur.
const role = request.headers["x-role"];
if (!requiredRoles.includes(role)) throw new ForbiddenException();
Düzeltme:
// DOĞRU — rolü sunucunun zaten doğruladığı JWT'den okur.
const role = request.user.role;
if (!requiredRoles.includes(role)) throw new ForbiddenException();
x-role başlık kalıbı, bir geliştiricinin JWT'yi aşağı akış isteğine eklemeyi unuttuğu anda tüm rol sistemini atlatır. Bu, derlenen, dağıtılan ve sessizce hakları düşüren bir kod yoludur. Rol okumasını request.user (JWT stratejisi tarafından doldurulan) üzerinde merkezileştirin ve hata kategorisi ortadan kalkar.
Girdi doğrulama
class-validator global ValidationPipe ile varsayılandır. Önemli olan varsayılan olmayan:
-
whitelist: trueveforbidNonWhitelisted: true. İstemci DTO'da olmayan bir alan gönderirse, isteği reddedin. Prototip kirliliği ve yanlışlıkla DTO sürüklenmesine karşı savunma. -
İş kurallarının ortama değil istek şekline bağlı olduğu uç noktalar için Joi / JSON Şema doğrulaması üzerinde bir FeatureFlag.
Ön uç: Next.js sertleştirme
Ara yazılım üzerinden başlıklar
Next.js ara yazılımı, sayfadan önce her istekte çalışır. HTML yanıtında ayarlanması gereken başlıklar için kullanın:
-
Content-Security-Policy (arkadaçın ayarladığı aynı politikayı yankılayın, eklenen
frame-ancestors 'none'ile). -
Strict-Transport-Security (HSTS, arka uçla eşleşen,
max-age=63072000ile). -
X-Content-Type-Options: nosniff.
-
Referrer-Policy: strict-origin-when-cross-origin.
-
Permissions-Policy: yalnızca gerçekten kullandığımız özellikler (Tolky için
camera=(self),microphone=(self); pazarlama yüzeyinde başka bir şey yok).
Görüntü optimizasyonu, uzak kalıpları ve next.config sürüklenme tuzağı
images.remotePatterns, next/image iyileştiricisi için izin listesidir. Tuzak:
-
Bir geliştirici yeni bir görüntü alanı ekler, gönderir ve unutur.
-
next-intl eklentisi çalışma zamanında çalışır ve
imagesbloğunu değiştirir — özel remotePatterns'inizi sessizce düşürür. -
Bu alandaki her görüntü iyileştiriciden 400 döndürmeye başlar.
Düzeltme, yapılandırmayı yeniden uygulayan bir çalışma zamanı muhafızı ve next.config'i runner aşamasına açıkça COPY yapan bir Dockerfile'dır. Muhafız üretimde sürüklenmeyi yakalar; Dockerfile kopyası yapı zamanında yakalar. Aynı neden için iki katman: next-intl eklentisinin görüntü optimizasyon politikanızı yemesine izin vermeyin.
Kimlik doğrulama uç noktalarını ön uçtan hız sınırı
Yapabiliyorsanız, arka uçta hız sınırı koyun. Yapamıyorsanız (ör. üçüncü taraf bir kimlik doğrulama sağlayıcısı), kimlik bilgisi doldurma girişimlerini tolere edilebilir bir hıza yavaşlatmak için ön uç ara yazılımında hız sınırı koyun. İki katman.
Paylaşılan hata: günlük enjeksiyonu
Denetlediğimiz her NestJS + Next.js projesinde gördüğümüz hata: kullanıcı girdisini kaçış olmadan enterpolasyon yapan günlük mesajları. Arama sorgusu: ${req.query.q} günlüğe kaydeden bir arama alanı, bir saldırgan q=\n[SAHTE GÜNLÜK GİRDİSİ]\n gönderdiği anda günlük enjeksiyon vektörü haline gelir.
Düzeltme tek satırdır: bir günlük satırına düşen herhangi bir kullanıcı girdisini kaçışlayın. Hemen hemen her günlüğe kaydetme kütüphanesinin sizin için bunu halleden bir escape veya yapılandırılmış günlüğe kaydetme kalıbı vardır. Kalıbı kullanın.
Kapanış ilkesi
Güvenlik bir özellik değildir. Bir hata sınıfının yokluğudur. Yukarıdaki yapılandırma, geçen yıl içinde üretime gönderildiğini gördüğümüz sınıfları ortadan kaldırır. Liste büyüyecektir. Bu yazıyı sabitleyin, üç ayda bir gözden geçirin ve sertleştirilmiş bir temel gönderin.
