---
title: "API Güvenlik Kontrol Listesi: Rate Limiting, CORS ve Input Validation"
description: "API güvenliği nasıl sağlanır? Express.js rate limiting, CORS yapılandırması, Zod ile input validation, SQL injection önleme ve Supabase anon key..."
date: 2026-04-13
category: guvenlik
tags: ["api", "guvenlik", "rate-limiting", "cors", "validation", "express"]
url: https://mikroerp.dev/blog/api-guvenlik-kontrol-listesi/
---

## API'niz Ne Kadar Güvenli?

Bir API endpoint'i yayına alındığında şu saldırılara açıktır:
- **Brute force**: Binlerce giriş denemesi
- **DDoS**: Sunucuyu aşırı istekle çökertme
- **SQL Injection**: Kötü niyetli SQL komutu çalıştırma
- **XSS**: Kullanıcıya zararlı script çalıştırtma
- **CORS bypass**: Yetkisiz origin'den veri çekme

## 1. Rate Limiting

Aynı IP'den gelen istek sayısını sınırlayın:

```typescript
// Express.js + express-rate-limit
import rateLimit from 'express-rate-limit';

// Genel limiter — tüm endpoint'ler
const generalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,   // 15 dakika
  max: 100,                    // IP başına max 100 istek
  message: { error: 'Çok fazla istek. Lütfen bekleyin.' },
  standardHeaders: true,       // RateLimit-* header'ları
  legacyHeaders: false,
});

// Auth limiter — daha sıkı
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,                     // 15 dakikada max 5 giriş denemesi
  message: { error: 'Çok fazla giriş denemesi.' },
});

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

## 2. CORS Ayarları

Cross-Origin isteklerde sadece güvenilir origin'lere izin verin:

```typescript
import cors from 'cors';

// ❌ YAPMAYIN — Her yerden erişim
app.use(cors());

// ✅ DOĞRUSU — Sadece belirli origin'ler
app.use(cors({
  origin: [
    'https://myapp.com',
    'https://admin.myapp.com',
    process.env.NODE_ENV === 'development' ? 'http://localhost:5173' : '',
  ].filter(Boolean),
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
}));
```

## 3. Input Validation (Zod)

Gelen veriyi **asla güvenmeyin**. Zod ile doğrulayın:

```typescript
import { z } from 'zod';

const CreateOrderSchema = z.object({
  customer_id: z.string().uuid(),
  items: z.array(z.object({
    product_id: z.string().uuid(),
    quantity: z.number().int().positive().max(10000),
    price: z.number().positive().max(999999.99),
  })).min(1).max(100),
  notes: z.string().max(500).optional(),
});

app.post('/api/orders', async (req, res) => {
  // Veriyi doğrula
  const result = CreateOrderSchema.safeParse(req.body);
  
  if (!result.success) {
    return res.status(400).json({ 
      error: 'Geçersiz veri', 
      details: result.error.flatten() 
    });
  }
  
  // result.data güvenli ve tipli
  const order = await createOrder(result.data);
  res.json(order);
});
```

## 4. SQL Injection Önleme

```typescript
// ❌ TEHLİKELİ — String birleştirme
const query = `SELECT * FROM users WHERE email = '${email}'`;
// email: "'; DROP TABLE users; --" → TABLODAKİ TÜM VERİ SİLİNİR

// ✅ GÜVENLİ — Parameterized query
const result = await pool.request()
  .input('email', sql.VarChar, email)
  .query('SELECT * FROM users WHERE email = @email');

// ✅ GÜVENLİ — Supabase SDK (otomatik parametrize)
const { data } = await supabase
  .from('users')
  .select('*')
  .eq('email', email);
```

## 5. HTTPS Zorlama

```typescript
// Production'da HTTP'yi HTTPS'e yönlendir
app.use((req, res, next) => {
  if (req.headers['x-forwarded-proto'] !== 'https' && 
      process.env.NODE_ENV === 'production') {
    return res.redirect(`https://${req.hostname}${req.url}`);
  }
  next();
});
```

## 6. Helmet ile HTTP Header Güvenliği

```typescript
import helmet from 'helmet';

app.use(helmet());
// Otomatik ekler:
// X-Content-Type-Options: nosniff
// X-Frame-Options: SAMEORIGIN
// X-XSS-Protection: 0 (CSP tercih edilir)
// Content-Security-Policy: ...
```

## Güvenlik Checklist

- [ ] Rate limiting aktif mi?
- [ ] CORS sadece izin verilen origin'lere açık mı?
- [ ] Tüm input'lar validate ediliyor mu?
- [ ] SQL sorguları parametrize mi?
- [ ] HTTPS zorlanıyor mu?
- [ ] Sensitive header'lar gizlenmiş mi? (Helmet)
- [ ] API key'ler environment variable'da mı?
- [ ] Error response'lar stack trace göstermiyor mu?
- [ ] Auth token'lar httpOnly cookie'de mi?
- [ ] File upload boyut limiti var mı?

## İlgili Yazılar

- [.env Güvenli Yönetimi](/blog/env-dosyalari-guvenli-yonetim/) — API key güvenliği
- [Supabase RLS](/blog/supabase-rls-cok-katmanli-yetkilendirme/) — Veritabanı seviyesi güvenlik
- [Supabase Auth](/blog/supabase-auth-react-kullanici-yonetimi/) — Token ve session yönetimi
- [SECURITY DEFINER vs INVOKER](/blog/postgresql-security-definer-vs-invoker/) — Fonksiyon güvenliği

---

*Bu rehber [OWASP API Security Top 10](https://owasp.org/www-project-api-security/) ve [Express.js Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html) kaynaklarına dayanarak hazırlanmıştır.*