Yazılarımız

OfisData

RATE LİMİTİNG UYGULAMAK VE KÖTÜYE KULLANIMI AZALTMAK

Bir API “çalışıyor” görünebilir ama bir gün ansızın yavaşlar: login denemeleri artar, arama endpoint’i botlara yem olur, ödeme adımı gereksiz isteklerle kilitlenir. Bu tablo, sadece güvenlik değil, maliyet ve müşteri deneyimi problemidir. Rate limiting, bu riskleri kontrol altına almak için en pratik savunma katmanlarından biridir.

Rate limiting; belirli bir süre penceresinde (ör. 1 dakika) belirli bir anahtar (IP, kullanıcı, token, API key) için istek sayısını sınırlandırmayı hedefler. Ama doğru uygulanmazsa gerçek kullanıcıyı da cezalandırır. Bu yüzden stratejiyi seçmek, store altyapısını belirlemek ve yanıt formatını standardize etmek kritik hale gelir.

Bu rehberde Node.js üzerinde rate limiting kurarken dikkat edilmesi gereken noktaları, örneklerle ve uygulanabilir adımlarla anlatacağız. Konuyu daha sistemli pratik etmek için nodejs eğitimi içeriğine de göz atabilirsiniz.

Bir geliştiricinin ekranında rate limit grafikleri, istek sayıları ve 429 yanıtlarını gösteren izleme paneli

Rate limiting mantığını anlamak ve hedefi netleştirmek

Rate limiting sadece “isteği durdurmak” değildir; amaç, sistemi öngörülebilir çalıştırmaktır. Ani trafik dalgasında servis ayakta kalır, pahalı endpoint’ler korunur ve kötüye kullanımın etkisi sınırlanır.

Kötüye kullanım senaryosunu tanımlamak ve sınırı buna göre koymak

Login brute force, search scraping, OTP bombardımanı, pahalı rapor endpoint’ine yoğun istek gibi farklı senaryolar farklı limit ister. Tek bir global limit her şeyi çözmez; hatta yanlış konumlanırsa kullanıcıyı kaçırabilir.

429 yanıtını tasarlamak ve istemci davranışını yönlendirmek

Limit aşıldığında 429 dönmek yeterli değildir. İstemcinin geri çekilmesini sağlayacak header’lar ve net bir mesaj gerekir. Retry fırtınasını önlemek için “ne zaman tekrar dene?” bilgisini taşımak önemlidir.


Limit anahtarını seçmek ve adil bir dağılım kurmak

Rate limiting “kime göre” uygulanacak? Bu seçim, hem doğruluğu hem de kullanıcı deneyimini belirler. IP bazlı limit basittir ama NAT arkasında çok kullanıcıyı aynı sepete koyabilir.

IP bazlı yaklaşımı kullanmak ve proxy katmanını dikkate almak

Reverse proxy veya load balancer varsa gerçek IP’yi doğru almak gerekir. Aksi halde tüm trafik tek IP gibi görünebilir. Bu yüzden güvenilir proxy ayarı yapmak kritik hale gelir.

Kullanıcı veya token bazlı yaklaşımı eklemek ve kötüye kullanımı hedeflemek

Giriş yapılmış kullanıcılar için userId bazlı limit daha adildir. API key kullanılıyorsa key bazlı limit, partner entegrasyonlarında kontrol sağlar. Hedef, masum trafiği kısıtlamadan saldırıyı daraltmaktır.


Stratejiyi seçmek ve burst trafiği yönetmek

Teknik olarak farklı rate limiting algoritmaları vardır. Pratikte iki yaklaşım öne çıkar: sabit pencere ve kaydırmalı pencere. Bir de “ani patlama” (burst) toleransı sunan token bucket benzeri yaklaşımlar vardır.

Sabit pencere yaklaşımını kullanmak ve basitliği korumak

“Her 60 saniyede en fazla 100 istek” kolaydır. Ancak pencere sınırında iki kez patlama olabilir: saniye 59’da 100, saniye 60’ta 100 daha. Kritik endpoint’lerde daha rafine yaklaşım düşünmek gerekir.

Burst toleransı vermek ve kullanıcı deneyimini korumak

Bazı ekranlar tek aksiyonda arka arkaya 5–10 istek üretebilir. Çok katı limit, gerçek kullanıcıyı engeller. Burada kısa süreli burst’e izin verip, uzun vadede sınırı korumak iyi denge sağlar.


Uygulamada middleware kurmak ve endpoint bazlı ayarlamak

Rate limiting’i global uygulamak yerine, risk ve maliyetine göre endpoint bazlı ayarlamak daha sağlıklıdır. Örneğin login daha sıkı, public içerik daha esnek olabilir.

Express üzerinde limiter bağlamak ve farklı rotalara ayrı kural koymak

Aşağıdaki örnek, genel API için bir limit; login için daha sıkı bir limit uygular. Mesaj formatı sade tutulur ve header’lar açık bırakılır.

const express = require("express");
const rateLimit = require("express-rate-limit");

const app = express();

const apiLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 120,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: "Too many requests", code: "RATE_LIMITED" }
});

const loginLimiter = rateLimit({
  windowMs: 10 * 60 * 1000,
  max: 20,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: "Too many login attempts", code: "LOGIN_RATE_LIMITED" }
});

app.use("/api", apiLimiter);
app.use("/api/auth/login", loginLimiter);

Hassas endpoint listesi çıkarmak ve kural setini sadeleştirmek

İlk adım, “neresi riskli?” sorusunu yanıtlamaktır. Sık görülen adaylar şunlardır:

  • Login / kayıt / OTP / şifre sıfırlama
  • Arama ve filtreleme endpoint’leri
  • Raporlama ve export işlemleri
  • Ödeme öncesi hesaplama ve stok kontrolü
  • Dosya yükleme ve medya işleme

Dağıtık sistemde store seçmek ve tutarlılığı sağlamak

Tek bir sunucuda memory store ile limit “gibi” çalışır. Ama birden fazla instance varsa, her instance kendi sayacını tutar ve kullanıcı daha yüksek trafik atabilir. Bu yüzden merkezi bir store gerekir.

Redis store kullanmak ve instance sayısı arttıkça ölçeklemek

Redis, rate limit sayaçları için yaygın bir tercihtir. Böylece hangi instance’a düşerse düşsün aynı anahtar aynı sayaçtan okunur. Bu yaklaşım, tutarlılığı artırmak için kritiktir.

Fail-open veya fail-closed kararını vermek ve risk yönetmek

Store erişimi kesilirse ne olacak? Fail-open, servis çalışmaya devam eder ama koruma zayıflar. Fail-closed, güvenliği korur ama kullanıcıyı engelleyebilir. Kritikliği yüksek endpoint’lerde farklı kararlar tercih edilebilir.

// Örnek pseudo akış: store hata verirse davranışı seçmek
function shouldAllowOnStoreError(route) {
  const criticalRoutes = ["/api/auth/login", "/api/auth/otp"];
  return !criticalRoutes.includes(route); // kritik değilse fail-open
}

Geri bildirim üretmek ve yanlış pozitifleri azaltmak

Rate limiting kurulduktan sonra “bitti” sanmak en yaygın yanılgıdır. Asıl iş, metrikleri izlemek ve yanlış pozitifleri azaltmaktır. Çünkü gerçek kullanıcıyı engellemek, gelir kaybına dönüşebilir.

Limit metriklerini izlemek ve 429 oranını anlamlandırmak

429 sayısı yükseliyorsa iki olasılık vardır: saldırı artmıştır veya limit aşırı sıkıdır. IP dağılımı, kullanıcı segmenti ve endpoint bazlı kırılım, doğru teşhisi hızlandırır.

Whitelist ve bypass kurgulamak ve güvenli istisna yönetmek

İç sistemler, sağlık kontrolü veya güvenilir entegrasyonlar için kontrollü istisna gerekebilir. Ancak istisna mekanizması kötüye kullanılabilir; bu yüzden API key, imzalı header veya network policy gibi ek kontrollerle desteklemek gerekir.

Bir ekip toplantısında 429 oranı, istek dağılımı ve endpoint bazlı limit ayarlarını tartışan ekran paylaşımı

Standart bir playbook oluşturmak ve ekipçe uygulamak

Rate limiting tek seferlik bir ayar değil, yaşayan bir standarttır. Yeni endpoint açıldığında kural setine dahil edilmezse, en zayıf halka orası olur. Bu yüzden küçük bir playbook işleri kolaylaştırır.

  1. Riskli endpoint’leri sınıflandırmak
  2. Limit anahtarını belirlemek (IP / user / token / key)
  3. Store kararını vermek (tek sunucu / Redis)
  4. 429 yanıt formatını standardize etmek
  5. Metrikleri izlemek ve düzenli revize etmek

Doğru kurgulanan rate limiting, kötüye kullanımı azaltır, servis stabilitesini korur ve maliyet kontrolünü güçlendirir. En önemlisi, saldırı anında panikle geçici çözüm üretmek yerine, önceden planlanmış bir savunma katmanı sunar.

 Vimaj