Gyakran előfordul, hogy egy szolgáltatás nem egyetlen monolitikus API végponton keresztül érhető el. Lehetnek verziózott végpontok (/v1/, /v2/), regionális szerverek (api.eu.service.com, api.us.service.com), vagy akár elfelejtett, régi, de még működő végpontok. Ha a sebességkorlátozás (rate limit) nem egy globális, központi rendszerben, hanem az egyes végpontok szintjén van implementálva, egy egyszerű, de hatékony megkerülési technika nyílik meg: a végpontok rotálása.
Ez a módszer lényegében a kérések szétosztását jelenti a rendelkezésre álló, funkcionálisan azonos végpontok között. Ha egy végpont eléri a korlátját, a kliens egyszerűen átvált a következőre a listájában, és folytatja a műveletet.
Az alapelv: A korlát kijátszása a forgalom megosztásával
Képzeld el, hogy egy szupermarketben több pénztár is van, de mindegyiknél van egy szabály: percenként csak egy terméket húzhatnak le. Ha te egyetlen pénztárhoz állsz be a tíz termékeddel, tíz percig fog tartani a vásárlás. De ha te és kilenc barátod egyszerre beálltok egy-egy pénztárhoz egy-egy termékkel, az egész folyamat egy perc alatt lezajlik. A rendszer teljes terhelése ugyanakkora, de a pénztárankénti korlátot nem sértettétek meg.
Az API végpontok rotálása pontosan ezt az elvet használja ki. A támadó azonosítja az összes lehetséges „pénztárat” (végpontot), és a kéréseit szétteríti közöttük, így egyik végpont sem érzékeli a teljes kérésszámot, csak a saját, töredéknyi terhelését.
A támadó a kéréseket ciklikusan elosztja a különböző végpontok között, így a teljes kérésszám (pl. 30 kérés/perc) jóval meghaladhatja az egyedi végpontok korlátját.
Felderítési technikák: Hol találhatók a rotálható végpontok?
A támadás sikeressége azon múlik, hány működő végpontot tudsz azonosítani. A felderítés több csatornán is történhet:
- API Dokumentáció: A legnyilvánvalóbb forrás. Gyakran listázzák a különböző verziókat vagy regionális hozzáférési pontokat.
- Kliensoldali kód elemzése: Egy webalkalmazás JavaScript forráskódja vagy egy mobilalkalmazás dekompilált kódja gyakran tartalmazza a lehetséges API hostneveket egy konfigurációs fájlban.
- DNS Enumeráció: Aldomainek keresése olyan nevekkel, mint
api-v2,api-staging,api-eu,api-us-west-1stb. gyakran vezethet eredményre. - HTTP Header-ök vizsgálata: Néha egy válasz header (pl.
Via,X-Served-By) elárulhatja a belső infrastruktúra elemeit vagy más potenciális végpontokat. - Path Guessing: Egyszerűen a verziószámok (
/v1/,/v2/,/v3/) vagy API prefixek (/api/,/rest/) variálása is felfedhet rejtett végpontokat.
Gyakorlati megvalósítás
A technika implementálása triviális. Egy egyszerű szkriptben definiálunk egy listát a felfedezett végpontokról, és minden egyes kérés előtt kiválasztjuk a következőt a listából, ciklikusan.
import requests
import itertools
# A felderített, funkcionálisan azonos végpontok listája
endpoints = [
"https://api.example.com/v1/generate",
"https://api.example.com/v2/generate",
"https://api-eu.example.com/v2/generate",
"https://legacy-api.example.com/generate"
]
# Egy ciklikus iterátort hozunk létre a listából
endpoint_cycler = itertools.cycle(endpoints)
prompt = "Mesélj egy viccet az AI-ról!"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
# Küldjünk 100 kérést a korlát megkerülésével
for i in range(100):
# Minden ciklusban a következő végpontot vesszük a listából
current_endpoint = next(endpoint_cycler)
try:
print(f"Kérés {i+1} küldése ide: {current_endpoint}")
response = requests.post(current_endpoint, json={"prompt": prompt}, headers=headers)
# ... válasz feldolgozása ...
except requests.exceptions.RequestException as e:
print(f"Hiba a(z) {current_endpoint} végponton: {e}")
Védekezési stratégiák
A végpontok rotálása elleni védekezés kulcsa a központosított és globális sebességkorlátozás. Ahelyett, hogy minden egyes API végpont vagy webszerver külön-külön kezelné a korlátokat, egy központi, megosztott állapotú rendszert (pl. Redis, Memcached) kell használni.
Ebben a modellben a korlátot egy globális azonosítóhoz kötik, mint például:
- API kulcs vagy User ID: A legerősebb azonosító. A rendszer minden kérésnél ellenőrzi, hogy az adott kulcs vagy felhasználó túllépte-e a globális kvótát, függetlenül attól, melyik végponton keresztül érkezett a kérés.
- IP-cím: Kevésbé megbízható (proxyk, NAT miatt), de azonosítatlan forgalom esetén ez az egyetlen opció. A logikának itt is központinak kell lennie.
A védelem tehát nem a támadás blokkolásáról szól, hanem az architektúra helyes kialakításáról. Ha a rate limit logika globálisan érvényesül, a végpontok rotálása hatástalanná válik, mivel a támadó ugyanazt a globális számlálót növeli, bármelyik „pénztárhoz” is áll be.