Kısıtsız kaynak tüketimi ve envanter yönetimi
- Kısıtsız kaynak tüketimi, tek istemcinin sınırsız istek ya da ağır sorguyla API'yi tüketmesidir; eksik envanter ise unutulmuş uçları açık bırakır.
- Sınırın dört boyutunu, nginx ile 429 dönen bir hız sınırını ve erişim kaydından eşiği aşan istemcileri ayıklamayı göreceksin.
- Gölge ve eski API sürümlerini envanter, sahip kaydı ve ağ geçidiyle görünür kılacaksın.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +50 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Altay Kargo bir kampanya duyurur ve takip ucunun trafiği birkaç dakikada on katına çıkar. Trafiğin bir kısmı gerçek müşterilerden gelir. Bir kısmı ise aynı adresten saniyede yüzlerce istek atan bir betiktir.
Sunucunun işlemcisi dolar, veritabanı bağlantı havuzu tükenir, gerçek müşteriler zaman aşımı görür. Aynı hafta bir güvenlik araştırmacısı, iki yıl önce kapatılması gereken eski bir API sürümünün hâlâ yanıt verdiğini bildirir. İki olay farklı görünür ama ortak bir kökleri vardır.
Birinde tek bir isteğin ne kadar iş yapabileceğine sınır konmamıştır. Ötekinde kimse API'nin nerede başlayıp nerede bittiğini bilmez.
İki risk: sınırsız istek ve unutulmuş uç
OWASP API Security Top 10 2023'ün dördüncü maddesi kısıtsız kaynak tüketimidir. Bir web sayfası tek istekte az kaynak harcar. Bir API ucu ise çoğu zaman ağır bir işlemi tek çağrıyla tetikler: büyük bir rapor üretir, küçük resim oluşturur, karmaşık bir arama çalıştırır.
Sunucu isteğin boyutuna, sıklığına ya da işlem süresine sınır koymazsa tek bir istemci sistemi kilitleyebilir. Bu her zaman kötü niyet gerektirmez; hatalı yazılmış bir istemci de saniyede binlerce istek atabilir. Maddenin 2023 sürümü bir boyut daha ekler: para.
SMS, e-posta ve bulut işlevleri çağrı başına ücretlendirilir. OWASP'ın örneğinde parola sıfırlama ucu her çağrıda SMS gönderir ve tanesi 0,05 dolardır. Binlerce kez tetiklenen çağrı dakikalar içinde ciddi bir faturaya dönüşür.
Dokuzuncu madde eksik envanter yönetimidir. Bir kuruluş kaç API'si olduğunu, hangi sürümlerin hâlâ çalıştığını ve hangi ortama açık olduğunu çoğu zaman tam bilmez. Eski bir sürüm kapatılmadan yenisi yayına girer. İkisi de aynı veritabanına erişir, ama yalnız yenisi güncel kontrolleri taşır.
Sektörde belgelenmemiş ya da sahipsiz uçlara gölge API, kapatılması unutulan eski sürümlere zombi API denir. OWASP'ın örneğinde bir beta API sunucusu, üretimdeki API ile aynı işlevi sunar ama hız sınırı taşımaz. Araştırmacı altı haneli parola sıfırlama kodunu o sunucu üstünden deneme yanılmayla bulur. Envanterde yer almayan bir uç izlenmez, güncellenmez ve savunulmaz.
Etkinlik 1 / 6
Aşağıdaki durumları kısıtsız kaynak tüketimi ya da envanter eksikliği olarak ayır.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/4 seçenek yerleşti.
Sınırın dört boyutu
Sınır dört boyutta kurulur ve her boyut ayrı bir kötüye kullanımı durdurur. İstek sıklığı, bir istemcinin belirli bir zaman diliminde kaç istek atabileceğini sınırlar; parola deneme ve veri kazıma betikleri burada takılır. Gövde boyutu, gönderilen verinin üst sınırını çizer. Bu sınır yoksa tek bir istek yüzlerce megabaytlık bir JSON ile ayrıştırıcıyı ve belleği doldurur.
Zaman aşımı, uzun süren bir sorgunun ne zaman kesileceğini belirler. O da yoksa ağır bir arama veritabanı bağlantısını dakikalarca tutar ve havuz tükenir.
Sayfalama, bir yanıtın tek seferde kaç kayıt döneceğini sınırlar. İstemci limit=1000000 gönderdiğinde sunucu bu değeri kendi üst sınırına indirmelidir. Dördü birlikte çalışmazsa biri açık kalır ve saldırgan oradan geçer.
Sınırın kime uygulanacağı da eşik kadar önemlidir. Yalnız IP adresine göre sınır koymak kolaydır, ama iki yönden zayıftır. Aynı kurumsal ağdaki yüzlerce gerçek kullanıcı tek bir adresten çıkar ve haksız yere engellenir.
Saldırgan ise isteklerini binlerce farklı adrese dağıtıp sınırın altında kalır. Bu yüzden sayaç birkaç anahtarda birden tutulur: IP adresi, oturumdaki kullanıcı, API anahtarı ve hedef hesap. Giriş ucunda hedef hesaba göre sayaç tutmak, dağıtık bir parola deneme saldırısını da yakalar.
Parola sıfırlama gibi pahalı uçlar genel sınırdan ayrı, çok daha düşük bir eşik taşır. Üçüncü taraf servislerde de harcama üst sınırı ve fatura uyarısı açılır.
Etkinlik 2 / 6
Altay Kargo'nun giriş ucu, dakikada kaç istekten sonra hız sınırına takılmalı? (Normal bir kullanıcı dakikada 2-3 kez dener.)
Tahminini kaydır, sonra gönder.
Çözümlü örnek: nginx ile hız sınırı
# http bloğu: istemci adresine göre iki sayaç alanı
limit_req_zone $binary_remote_addr zone=api_genel:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=api_giris:10m rate=20r/m;
server {
location /api/ {
limit_req zone=api_genel burst=10 nodelay;
limit_req_status 429;
client_max_body_size 1m;
proxy_pass http://uygulama;
}
location = /api/giris {
limit_req zone=api_giris burst=5 nodelay;
limit_req_status 429;
proxy_pass http://uygulama;
}
}Yapılandırmayı satır satır oku. limit_req_zone, istemci adresine göre bir sayaç alanı açar. $binary_remote_addr adresi kısa ikili biçimde tutar.
nginx belgesine göre 1 MB'lık alan yaklaşık 16 bin adresin durumunu taşır. İlk alan genel API için saniyede 5 istek, ikinci alan giriş ucu için dakikada 20 istek tanımlar. limit_req satırı alanı bir konuma bağlar.
burst değeri anlık taşmaya pay bırakır: oran aşılsa da belirli sayıda fazla istek kabul edilir. nodelay ile bu paydaki istekler bekletilmeden işlenir, payı aşan istek hemen reddedilir. client_max_body_size gövdeyi 1 MB ile sınırlar ve aşan isteğe 413 döner. nginx sınırlamayı sızdıran kova (leaky bucket) yöntemiyle yapar.
Burada sık yapılan bir hata vardır. nginx sınırı aşan isteğe varsayılan olarak 503 döner. 503 sunucu arızası gibi okunur; istemci sorunun kendisinde olduğunu anlamaz, izleme panosu da yanlış alarm üretir.
limit_req_status 429 satırı bu yüzden eklenir. 429 Too Many Requests kodu RFC 6585 ile tanımlanmıştır ve istemcinin çok sık istek gönderdiğini söyler. Yanıt, ne kadar bekleneceğini bildiren Retry-After başlığını taşıyabilir; nginx bu başlığı kendiliğinden eklemez.
Kalan kotayı bildiren RateLimit ve RateLimit-Policy başlıkları için IETF'te bir taslak üstünde çalışılıyor, henüz RFC değildir. Yeni bir sınırı açmadan önce limit_req_dry_run ile kuru çalıştırma yapabilirsin. İstek reddedilmez, yalnız sayılır ve kayda geçer.
$ for i in $(seq 1 8); do curl -s -o /dev/null -w "%{http_code} " -X POST -d @deneme.json https://api.altaykargo.example/api/giris; done
401 401 401 401 401 401 429 429Döngü giriş ucuna sekiz istek gönderir. İlk istek oranın içindedir. Sonraki beş istek burst payına girer ve nodelay sayesinde bekletilmeden uygulamaya ulaşır; uygulama yanlış parola için 401 döner.
Yedinci istekte pay dolmuştur. nginx isteği uygulamaya hiç iletmeden 429 ile keser.
Kova dakikada 20 istek hızıyla, yani üç saniyede bir istek kadar boşalır. Bu sınamayı yalnız kendi lab ortamında ya da yazılı iznin olan bir sistemde yap. Gerçek bir giriş ucunda bu katman tek başına yetmez. Hesap başına sayaç ve çok adımlı doğrulamayla birlikte çalışır.
Etkinlik 3 / 6
Bir istemci bu uca aynı saniye içinde art arda beş istek gönderiyor. Dördüncü isteğin yanıt kodu ne olur?
Önce kodu oku, sonra çıktıyı seç.
limit_req_zone $binary_remote_addr zone=rapor:10m rate=1r/s;
location /api/rapor {
limit_req zone=rapor burst=2 nodelay;
proxy_pass http://uygulama;
}Tespit: kayıttan eşiği aşanları çıkarmak
Hız sınırı kurulmadan önce de trafik bir iz bırakır. Altay Kargo'nun güvenlik ekibi kampanya günü takip ucundaki yükü inceler. Önce erişim kaydının son dakikasını erisim.log adlı ayrı bir dosyaya alır, sonra her adresin istek sayısını sayar.
Kaydın her satırı istemci adresiyle başlar. Bu yüzden ilk sütunu ayırmak, sıralamak ve tekrarları saymak yeterlidir. Sıralama adımı atlanamaz.
uniq yalnız art arda gelen aynı satırları birleştirir; sırasız listede aynı adres birkaç ayrı satırda sayılır. Sonuç büyükten küçüğe dizilir ve eşiği aşan adresler seçilir. Eşik normal kullanıcının davranışından türetilir. Bir müşteri takip ucunu dakikada birkaç kez çağırır, elliden fazla istek insan davranışının dışında kalır.
$ awk '{print $1}' erisim.log | sort | uniq -c | sort -rn | head -4
412 203.0.113.45
61 198.51.100.7
9 192.0.2.18
4 192.0.2.77Çıktıyı oku. 203.0.113.45 adresi bir dakikada 412 istek atmıştır; bu saniyede yaklaşık yedi isteğe denk gelir ve bir betiğin işaretidir. 198.51.100.7 eşiğin biraz üstündedir, daha dikkatli bakmak gerekir.
Tek bir adresten gelen yoğun trafik her zaman kötü niyetli değildir. Bir iş ortağının toplu entegrasyonu, bir izleme aracı ya da aynı çıkış adresini paylaşan bir ofis de benzer iz bırakır. Alarmı otomatik engellemeye bağlamadan önce adresin hangi uçları çağırdığına bak.
Hep aynı takip numarası listesini dolaşan adres veri kazıyordur. Giriş ucunu farklı kullanıcı adlarıyla deneyen adres kimlik bilgisi doldurmayı akla getirir. Yalnız sağlık denetimi ucunu çağıran adres büyük olasılıkla izleme aracıdır.
Bu davranışları adlandırmak için OWASP'ın web uygulamalarına yönelik otomatik tehditler kataloğunu kullanabilirsin. Katalog her kötüye kullanımı bir OAT numarasıyla tanımlar. OAT-008 kimlik bilgisi doldurmadır: başka yerden sızmış kullanıcı adı ve parola çiftleri toplu denenir. OAT-011 kazımadır: içerik ya da fiyat bilgisi otomatik toplanır.
OAT-005 karaborsacılıktır (scalping): sınırlı stoktaki ürün betikle kapılır. OAT-015 hizmet engellemedir. Ortak bir dil, tespit kurallarını ve olay raporlarını tutarlı kılar.
Kural yalnız "çok istek" demek yerine hangi tehdidi aradığını söylerse yanıt da netleşir. Kazımaya sayfalama ve kota, kimlik bilgisi doldurmaya hesap başına sayaç ve çok adımlı doğrulama gerekir.
Etkinlik 4 / 6
Erişim kaydından, son bir dakikada 50'den çok istek atan istemci adreslerini çıkaran hattı kur.
Parçalara tıklayarak komutu soldan sağa kur.
Envanter, gölge API ve ağ geçidi
Envanteri kapatmak tek bir listeyle olmaz, sürekli bir süreç ister. Her API bir sahiple, bir sürüm numarasıyla, bir ortam bilgisiyle ve bir yaşam döngüsü durumuyla kayda geçer. OWASP ayrıca her API'nin hangi veriyi hangi üçüncü tarafla paylaştığının yazılmasını ister.
Eski sürüm kapatılacaksa önce istemcilere haber verilir, sonra belirlenen tarihte devre dışı bırakılır. HTTP'de bu duyuru için Deprecation (RFC 9745) ve Sunset (RFC 8594) başlıkları vardır. Ağ trafiği dinlenerek gölge API'ler de bulunur.
Belgede olmayan ama trafik alan bir uç envanterden kaçmış demektir. Test ve hazırlık ortamları da envanterin parçasıdır. Üretim verisinin kopyasını taşıyıp üretim kontrollerini taşımayan bir test sunucusu, saldırgan için en kısa yoldur.
API ağ geçidi bu işin merkezidir. Bütün istekler tek bir noktadan geçer. Hız sınırı, gövde boyutu, kimlik doğrulama ve kayıt tutma tek yerde uygulanır. Yeni bir uç ağ geçidine tanımlanmadan dışarıdan trafik alamaz; böylece envanter kendiliğinden güncel kalır.
Ağ geçidi her istemciye ayrı kota da verebilir. İş ortaklarına verilen anahtarlar kendi havuzlarında sayılır. Bir ortağın hatalı entegrasyonu saniyede binlerce istek atsa bile yalnız kendi kotasını tüketir. Ağ geçidi bir de varsayılan değerleri korur: istemci sayfalama parametresi göndermese bile yanıt belirli bir kayıt sayısını aşmaz.
Derinleş:Sızdıran kova, jeton kovası ve pencere
Hız sınırlayıcıların çoğu birkaç modelden birine dayanır. Sızdıran kova (leaky bucket) modelinde istekler bir kovaya dolar, kova sabit bir hızla boşalır. Kova taşarsa yeni istek reddedilir. nginx bu modeli kullanır; burst değeri kovanın derinliği, rate değeri boşalma hızıdır.
Jeton kovası (token bucket) modelinde kova sabit hızla jetonla dolar ve her istek bir jeton harcar. Biriken jetonlar kısa bir patlamaya yer açar, jeton bitince istek bekler ya da reddedilir. İki model de sabit pencere sayacından daha düzgün davranır.
Sabit pencerede dakikada 60 istek sınırı, bir dakikanın son saniyesinde 60 ve sonrakinin ilk saniyesinde 60 istek atan istemciyi kaçırır. İki saniyede 120 istek geçer. Kayan pencere ve kova modelleri bu sınır taşmasını yumuşatır.
Etkinlik 5 / 6
Bir API ağ geçidi, sayfalama parametresi olmayan bir arama ucuna karşı hangi önlemi almalı?
Etkinlik 6 / 6
Doğru mu, yanlış mı?
Bir iş ortağına verilen API anahtarının hız sınırı, dahili kullanıcılardan ayrı bir havuzda tutulmalıdır.
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.