İçeriğe geç
Node.js

Node.js Güvenlik: Helmet ve CORS Yapılandırması

Tarık Tunç
Node.js Güvenlik: Helmet ve CORS Yapılandırması

Node.js Güvenlik: Helmet ve CORS Yapılandırması

Web uygulaması güvenliği, geliştirme sürecinin her aşamasında dikkate alınması gereken kritik bir konudur. Node.js ve Express uygulamalarında Helmet ve CORS middleware'leri, en yaygın güvenlik tehditlerini engellemek için temel savunma katmanları oluşturur. Bu rehberde HTTP güvenlik başlıklarını, CORS politikalarını ve production-ready güvenlik yapılandırmalarını detaylı olarak inceleyeceğiz.

1. HTTP Güvenlik Başlıkları ve Tehditler

Modern web uygulamaları çeşitli güvenlik tehditleriyle karşı karşıyadır:

  • XSS (Cross-Site Scripting): Kötü amaçlı JavaScript enjeksiyonu
  • Clickjacking: Sayfa üzerinde görünmez iframe ile tıklama çalma
  • MIME Sniffing: Tarayıcının dosya türünü yanlış yorumlaması
  • Man-in-the-Middle: HTTPS olmadan veri dinleme
  • CSRF: Kullanıcının haberi olmadan istek gönderilmesi

2. Helmet Kurulum ve Yapılandırma

Helmet, Express uygulamalarına güvenlik başlıkları ekleyen bir middleware koleksiyonudur. Tek satır ile 15'ten fazla güvenlik başlığı ayarlar.

# Kurulum
npm install helmet
const express = require('express');
const helmet = require('helmet');

const app = express();

// Varsayılan yapılandırma — tüm başlıkları etkinleştirir
app.use(helmet());

// Veya özelleştirilmiş yapılandırma
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "https://cdn.example.com"],
      styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
      imgSrc: ["'self'", "data:", "https:"],
      fontSrc: ["'self'", "https://fonts.gstatic.com"],
      connectSrc: ["'self'", "https://api.example.com"],
      frameSrc: ["'none'"],
      objectSrc: ["'none'"],
      upgradeInsecureRequests: [],
    },
  },
  crossOriginEmbedderPolicy: true,
  crossOriginOpenerPolicy: { policy: "same-origin" },
  crossOriginResourcePolicy: { policy: "same-origin" },
  hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
  referrerPolicy: { policy: "strict-origin-when-cross-origin" },
}));

Helmet Başlıkları Detaylı

BaşlıkKoruduğu TehditVarsayılan
Content-Security-PolicyXSS, veri enjeksiyonuAktif
X-Content-Type-OptionsMIME sniffingnosniff
X-Frame-OptionsClickjackingSAMEORIGIN
Strict-Transport-SecurityHTTP downgradeAktif
X-XSS-ProtectionEski tarayıcılarda XSS0
Referrer-PolicyBilgi sızıntısıno-referrer
X-DNS-Prefetch-ControlDNS sızıntısıoff

3. Content Security Policy (CSP) Detaylı

CSP, XSS saldırılarına karşı en güçlü savunma mekanizmalarından biridir.

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],

    // JavaScript kaynakları
    scriptSrc: [
      "'self'",
      "'nonce-randomValue'",   // Nonce tabanlı
      "https://cdn.example.com",
    ],

    // CSS kaynakları
    styleSrc: [
      "'self'",
      "'unsafe-inline'",       // Inline CSS'e izin (dikkatli kullanın)
      "https://fonts.googleapis.com",
    ],

    // Resim kaynakları
    imgSrc: ["'self'", "data:", "https:", "blob:"],

    // API bağlantıları
    connectSrc: [
      "'self'",
      "https://api.example.com",
      "wss://ws.example.com",  // WebSocket
    ],

    // Font kaynakları
    fontSrc: ["'self'", "https://fonts.gstatic.com"],

    // İframe kaynakları
    frameSrc: ["https://www.youtube.com"],

    // Form action hedefleri
    formAction: ["'self'"],

    // Base URI
    baseUri: ["'self'"],

    // Object/embed engelleme
    objectSrc: ["'none'"],
  },
  // CSP ihlallerini raporla
  reportOnly: false,
}));

// Nonce tabanlı CSP (her istek için benzersiz)
app.use((req, res, next) => {
  const nonce = crypto.randomBytes(16).toString('base64');
  res.locals.cspNonce = nonce;
  next();
});

app.use(helmet.contentSecurityPolicy({
  directives: {
    scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
  },
}));
İpucu: CSP'yi ilk aşamada reportOnly: true modunda çalıştırın. Bu sayede mevcut işlevselliği bozmadan hangi kaynakların engelleneceğini görebilirsiniz.

4. CORS Yapılandırması

CORS (Cross-Origin Resource Sharing), farklı domain'lerden gelen istekleri kontrol etmenizi sağlar.

# Kurulum
npm install cors
const cors = require('cors');

// Basit yapılandırma — tek origin
app.use(cors({
  origin: 'https://www.example.com',
}));

// Çoklu origin desteği
const allowedOrigins = [
  'https://www.example.com',
  'https://admin.example.com',
  'https://app.example.com',
];

app.use(cors({
  origin: function(origin, callback) {
    // origin undefined ise (Postman, curl gibi araçlar)
    if (!origin) return callback(null, true);

    if (allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('CORS politikası tarafından engellendi'));
    }
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
  exposedHeaders: ['X-Total-Count', 'X-Request-ID'],
  credentials: true,
  maxAge: 86400, // Preflight cache süresi (24 saat)
}));

Route-Specific CORS

// Sadece belirli route'lara CORS uygulama
const publicCors = cors({ origin: '*', methods: ['GET'] });
const privateCors = cors({
  origin: allowedOrigins,
  credentials: true,
});

// Public API — herkese açık
app.get('/api/public/data', publicCors, (req, res) => {
  res.json({ data: 'public' });
});

// Private API — sadece izin verilen origin'ler
app.post('/api/private/data', privateCors, (req, res) => {
  res.json({ data: 'private' });
});

5. Rate Limiting

# Kurulum
npm install express-rate-limit
const rateLimit = require('express-rate-limit');

// Genel rate limit
const generalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 dakika
  max: 100,                  // pencere başına 100 istek
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Çok fazla istek. Lütfen daha sonra tekrar deneyin.' },
});

app.use('/api/', generalLimiter);

// Auth endpoint'leri için daha sıkı limit
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: { error: 'Çok fazla giriş denemesi.' },
});

app.use('/api/auth/', authLimiter);

6. Ek Güvenlik Middleware'leri

// Input sanitization
const mongoSanitize = require('express-mongo-sanitize');
app.use(mongoSanitize()); // NoSQL injection engelleme

// XSS temizleme
const xss = require('xss-clean');
app.use(xss());

// HPP (HTTP Parameter Pollution) koruması
const hpp = require('hpp');
app.use(hpp());

// Body boyut sınırlama
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: true, limit: '10kb' }));

7. Production Güvenlik Checklist

// Tüm güvenlik middleware'lerini birleştiren tam yapılandırma
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');

const app = express();

// 1. Helmet — güvenlik başlıkları
app.use(helmet());

// 2. CORS — cross-origin kontrol
app.use(cors({
  origin: process.env.ALLOWED_ORIGINS?.split(',') || 'https://www.example.com',
  credentials: true,
}));

// 3. Rate limiting
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));

// 4. Body parser sınırları
app.use(express.json({ limit: '10kb' }));

// 5. Trust proxy (reverse proxy arkasında)
app.set('trust proxy', 1);

// 6. X-Powered-By başlığını kaldır (helmet zaten yapar)
app.disable('x-powered-by');

// 7. Hata detaylarını gizle
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    error: process.env.NODE_ENV === 'production'
      ? 'Sunucu hatası'
      : err.message,
  });
});
Uyarı: cors({ origin: '*' }) ile credentials: true aynı anda kullanılamaz. Credentials kullanıyorsanız origin'i açıkça belirtmelisiniz.

Sonuç

Node.js uygulamalarında güvenlik, birden fazla katmanda uygulanmalıdır. Helmet ile HTTP güvenlik başlıklarını ayarlamak, CORS ile cross-origin erişimi kontrol etmek ve rate limiting ile kötüye kullanımı engellemek temel adımlardır. CSP politikası XSS saldırılarına karşı güçlü bir savunma sunar. Bu middleware'leri projenizin başlangıcında yapılandırmak, güvenlik açıklarını erken aşamada önlemenizi sağlar. Güvenlik sürekli bir süreçtir; bağımlılıklarınızı güncel tutun ve düzenli güvenlik denetimleri yapın.

Kaynaklar

İlgili Yazılar