Mesterséges Intelligencia API Védelem: Terheléskorlátozás (Rate Limiting és Throttling) beállítása a túlterheléses támadások ellen

2025.10.17.
AI Biztonság Blog

A te AI API-dnak van kidobóembere? Vagy csak egy tárva-nyitva álló ajtó?

Képzeld el a helyzetet. Péntek este van, a rendszered monitorjai zölden világítanak. Elégedetten dőlsz hátra, talán épp elindítanál egy meccset a kedvenc játékodban. Aztán pittyen egy riasztás. Aztán még egy. Tíz perc múlva az AI modelledet kiszolgáló API válaszideje az egekben, a felhőszolgáltatód számlálója pedig úgy pörög, mint egy megvadult taxióra. A felhasználók panaszkodnak, a főnököd hívogat. A hétvégédnek annyi.

Mi történt? Valaki épp most hajt végre egy túlterheléses támadást az API-d ellen. De ez nem a régi vágású, „küldjünk rá milliónyi üres pinget” stílusú támadás. Ez sokkal alattomosabb. Sokkal költségesebb. Ez egy AI-specifikus támadás.

Kapcsolati űrlap

AI Biztonság kérdésed van? Itt elérsz minket:

A legtöbb fejlesztő úgy gondol az API-jára, mint egy étteremre. Jön a vendég (kérés), leadja a rendelést, a konyha (a backend) elkészíti, a pincér (az API) pedig kihozza a választ. De egy AI API nem egy átlagos étterem. Ez egy Michelin-csillagos, molekuláris gasztronómiával foglalkozó hely, ahol minden egyes fogás egyedi műalkotás, amihez rengeteg idő, energia és drága alapanyag kell.

És te ezt az éttermet őrizetlenül hagytad. Nincs senki az ajtóban, aki megszámolja, hányan jönnek be, vagy aki szólna, ha egy 100 fős csoport egyszerre akarná elfoglalni az összes asztalt, hogy aztán csak egy pohár vizet rendeljenek.

A Rate Limiting és a Throttling nem csak egy technikai beállítás. Ez a te digitális kidobóembered, aki megvédi a drága erőforrásaidat a rosszindulatú vagy egyszerűen csak a rosszul megírt kliensektől.

Ebben a posztban nem arról fogok papolni, hogy „a biztonság fontos”. Ezt te is tudod. Arról fogok beszélni, hogy az AI modellek miért jelentenek egy teljesen új játszóteret a támadóknak, és hogy a klasszikus védelmi vonalak miért omlanak össze, mint a kártyavár. Aztán megmutatom a fegyvereket, amikkel visszavághatsz.

Miért vérzik el egy hagyományos API-védelem egy AI modell kapujában?

Mielőtt belevágnánk a megoldásokba, meg kell értened a harcteret. Egy AI API sebezhetősége nem egy bug a kódban. A sebezhetőség maga a működési elv. Három fő oka van annak, hogy az AI-rendszerek különösen ki vannak téve a túlterhelésnek.

1. Aszimmetrikus erőforrás-igény: A „Denial of Wallet” támadás

Egy hagyományos REST API esetében egy kérés-válasz ciklus általában olcsó. Lekérsz egy felhasználói profilt? Az adatbázisból egy gyors indexelt keresés, és már repül is a JSON. A támadónak és a szervernek nagyjából ugyanannyi energiájába kerül a művelet.

Na, egy AI modellnél ez a szimmetria felborul. Teljesen.

Gondolj egy képgeneráló modellre. A támadó küld egy 500 karakteres promptot. Ez neki szinte semmibe nem kerül. A te szervered viszont beizzítja a méregdrága GPU-kat, lefoglal több gigabájt VRAM-ot, és percekig számol, hogy legeneráljon egy képet egy „asztronauta lovon, a Holdon, szürrealista stílusban”. A támadó egy filléres befektetéssel dollárok vagy akár több tíz dollárnyi számítási költséget ver a nyakadba. Minden egyes kéréssel.

Ezt hívjuk Denial of Service (DoS) helyett Denial of Wallet (DoW) támadásnak. A cél nem feltétlenül az, hogy leállítsa a szolgáltatásodat – bár az is bekövetkezik –, hanem hogy pénzügyileg kivéreztesse a cégedet. Egy jól időzített, pár ezer kérésből álló támadás a hónap végén olyan felhőszámlát eredményezhet, amitől a pénzügyi osztályon sikítófrászt kapnak.

Az analógia? Mintha valaki bemenne egy szobrászhoz, és rendelne ezer egyedi márványszobrot, de csak egy centet fizetne darabjáért. A szobrász belerokkan, a megrendelőnek meg alig került valamibe.

Támadó (Attacker) POST /generate {„prompt”: „…”} Költség (Cost) ~0.001 $ AI Szerver (Your Server) GPU pörög… VRAM lefoglalva… Modell számol… Költség (Cost) ~5.00 $ Aszimmetrikus költség: Egy olcsó kérés drága választ generál.

2. Kiszámíthatatlan és hosszú válaszidők

Egy adatbázis-lekérdezés általában milliszekundumokban mérhető. Ha ennél lassabb, ott valami baj van. Egy AI modellnél viszont a válaszidő a bemenettől függően drasztikusan változhat. Egy egyszerű kérdésre egy chatbot azonnal válaszol. De ha megkéred, hogy írjon egy 5000 szavas esszét a reneszánsz költészet és a kvantummechanika kapcsolatáról, akkor percekig is eltarthat a válasz.

Ez a kiszámíthatatlanság megöli a hagyományos terheléselosztókat és a timeout-alapú védelmeket. Honnan tudja a rendszer, hogy egy 30 másodperce futó kérés egy legitim, komplex feladat, vagy egy beakadt, erőforrásokat zabáló folyamat? A támadók ezt kihasználva olyan kéréseket küldhetnek, amelyek a lehető leghosszabb ideig kötik le a rendszered erőforrásait, ezzel megbénítva a többi, legitim felhasználót.

3. Állapottartó (Stateful) interakciók

Sok AI alkalmazás, különösen a chatbotok, nem független kérés-válasz párokban gondolkodnak. Egy beszélgetés kontextust épít. A modellnek emlékeznie kell az előző kérdésekre és válaszokra, hogy koherens tudjon maradni. Ez azt jelenti, a szervernek minden felhasználói interakcióhoz egyre növekvő állapotot kell a memóriában tartania.

Egy támadó könnyedén kihasználhatja ezt. Elindít több ezer párhuzamos, soha be nem fejezett beszélgetést. Mindegyikhez küld pár üzenetet, hogy a szerver felépítse a kontextust, majd otthagyja az egészet lógva a levegőben. Ezek az „zombi” beszélgetések lassan felemésztik a szerver memóriáját, amíg az végül összeomlik. Ez egy sokkal finomabb támadás, mint a nyers erő, és a legtöbb egyszerű korlátozás átsiklik felette.

A védelem első vonala: Rate Limiting

Oké, a helyzet komoly. Mit tehetsz? Az első és legfontosabb lépés a Rate Limiting, vagyis a kérések számának korlátozása. Ez a digitális kidobóembered, aki az ajtóban áll egy számlálóval a kezében.

A Rate Limiting azt mondja: „Figyelj, te (egy adott IP címről, API kulccsal, felhasználói fiókkal) egy bizonyos időablakban (pl. percenként) csak X számú kérést küldhetsz.” Ha túlléped ezt a limitet, az API egy 429 Too Many Requests HTTP hibakóddal válaszol, és elutasítja a kérést.

Egyszerűen hangzik, de az ördög a részletekben rejlik. Többféle algoritmus létezik, mindegyiknek megvan a maga előnye és hátránya.

Algoritmusok a pult alatt

1. Fixed Window Counter (Fix ablakos számláló)

Ez a legegyszerűbb megközelítés. Veszünk egy időablakot, mondjuk egy percet (1:00:00-tól 1:00:59-ig). Létrehozunk egy számlálót. Minden bejövő kérés növeli a számlálót. Ha a számláló eléri a limitet (pl. 100), minden további kérést elutasítunk az ablak végéig. Amikor az óra átfordul 1:01:00-ra, a számlálót lenullázzuk.

Előnye: Pofonegyszerű implementálni és nagyon gyors.

Hátránya: Sebezhető a peremeken. Mi van, ha egy támadó 1:00:59-kor elküld 100 kérést, majd 1:01:00-kor még 100-at? Két másodperc alatt 200 kérést engedtünk át, ami rövid időre a duplája a tervezett terhelésnek. Ez a tüske pont elég lehet, hogy megbillentsen egy érzékeny rendszert.

Fixed Window Counter – A peremeken jelentkező tüske 00:59 01:00 01:01 1. Időablak (Limit: 100) 2. Időablak (Limit: 100) Limit Tüske (Burst) A támadó az ablak végén (00:59) és az új ablak elején (01:00) is küld kéréseket, így rövid időn belül a limit dupláját éri el.

2. Token Bucket (Token vödör)

Képzelj el egy vödröt, aminek van egy bizonyos kapacitása (pl. 100 token). A rendszer egyenletes ütemben, folyamatosan tesz új tokeneket a vödörbe (pl. másodpercenként 2-t), amíg az tele nem lesz. Minden bejövő API kérés „kivesz” egy tokent a vödörből. Ha van token, a kérés átmegy. Ha a vödör üres, a kérés elutasításra kerül.

Előnye: Ez a módszer sokkal simább és rugalmasabb. Lehetővé tesz rövid ideig tartó, a steady-state rátát meghaladó forgalmi tüskéket (bursts), hiszen a kliens felhasználhatja a felgyülemlett tokeneket. Amikor elfogynak, a sebessége lekorlátozódik a tokenek újratermelődésének ütemére. Ez a legtöbb modern rendszer által preferált megoldás.

Hátránya: Kicsit bonyolultabb implementálni, mivel két paramétert kell kezelni: a vödör méretét (burst rate) és a tokenek újratöltési sebességét (sustained rate).

Token Bucket Algoritmus Token újratöltés (pl. 2/sec) Token Vödör Kapacitás: 100 Jelenleg: 78 token Bejövő kérések Kérés -1 token Van token? Igen API Feldolgozás Nem 429 Hiba A kérések tokeneket „fogyasztanak”. Ha a vödör kiürül, a kérések elutasításra kerülnek.

3. Leaky Bucket (Lyukas vödör)

Ez a Token Bucket egyfajta inverze. A bejövő kéréseket egy sorba (a vödörbe) tesszük. A rendszer egy fix, állandó ütemben veszi ki a kéréseket a sorból feldolgozásra (mintha a vödör alja egyenletesen szivárogna). Ha a sor megtelik, mert a kérések gyorsabban érkeznek, mint ahogy a rendszer fel tudja dolgozni őket, a további kérések eldobódnak.

Előnye: Garantálja a feldolgozás egyenletes, kiszámítható sebességét. Tökéletes arra, hogy megvédjen egy backend szolgáltatást a hirtelen forgalmi tüskéktől, és „kisimítsa” a terhelést.

Hátránya: Nem engedélyez burstöket. Egy legitim felhasználó, aki hirtelen több kérést küldene, ugyanúgy várakozásra vagy elutasításra kényszerül, mint egy támadó.

Rate Limiting vs. Throttling: A Finom Különbség

Gyakran szinonimaként használják őket, de van egy fontos különbség. A Rate Limiting általában a kérések elutasítását jelenti, ha a limitet átlépték (a kidobó azt mondja: „Sajnálom, ma estére tele vagyunk, gyere vissza holnap.”). A Throttling (fojtás, lassítás) egy finomabb megközelítés: ahelyett, hogy azonnal elutasítaná a kérést, a rendszer lelassítja a feldolgozást, sorba állítja a kéréseket (a kidobó azt mondja: „Pillanat, telt ház van. Állj be a sorba, és ha valaki kijön, bemehetsz.”).

A gyakorlatban a két technika gyakran együtt működik. Egy rendszer használhat throttlingot egy bizonyos pontig, hogy kezelje a kisebb terhelési csúcsokat, de ha a sor túl hosszúra nyúlik, átvált kemény rate limitingre, és elkezdi eldobálni a kéréseket.

Szempont Rate Limiting (Korlátozás) Throttling (Lassítás)
Fő cél A szerver védelme a túlterheléstől egy fix limit felett. A bejövő kérések feldolgozási sebességének simítása, egyenletessé tétele.
Viselkedés a limit felett Azonnal elutasítja a kérést (pl. HTTP 429). Sorba állítja a kérést, és később dolgozza fel, amikor van szabad kapacitás.
Felhasználói élmény Frusztráló lehet, mert a kérést újra kell küldeni. Kiszámítható. A válaszidő megnő, de a kérés végül (általában) sikeres lesz.
Analógia A klub kidobója, aki egy bizonyos vendégszám felett senkit nem enged be. Az autópálya-felhajtó előtti lámpa, ami csak percenként enged fel pár autót.
Ideális felhasználás Publikus API-k védelme, DoS/DoW támadások megelőzése. Belső rendszerek közötti kommunikáció, ahol egy szolgáltatás nem bírja a hirtelen terhelést.

A stratégia: Hol és Mi alapján korlátozz?

Oké, megvan az elmélet. De a gyakorlatban hol kell ezt beállítani, és milyen alapon? A „mindenkinek 100 kérés/perc” egy rossz, sőt, veszélyes stratégia egy AI API esetében.

Implementációs szintek

  1. API Gateway (pl. Kong, Tyk, AWS API Gateway): Ez a leggyakoribb és általában a legjobb hely a kezdéshez. Az API Gateway az összes bejövő forgalom előtt ül, így egy központi helyen, a te alkalmazáskódodtól függetlenül tudod kezelni a korlátozást. A legtöbb gateway beépítve támogatja a legnépszerűbb algoritmusokat.
  2. Load Balancer / Reverse Proxy (pl. NGINX, HAProxy): Hasonló az API Gateway-hez, de általában alacsonyabb szintű. Jól működik egyszerű, IP-cím alapú korlátozásra, de a finomhangolt, felhasználó-specifikus szabályokhoz már nem biztos, hogy elég rugalmas.
  3. Alkalmazás szint (Application Level): A legrugalmasabb, de egyben a legbonyolultabb megoldás. Itt, a saját kódodban implementálod a korlátozást. Ez azért lehet jó, mert itt van a legtöbb kontextusod. Itt tudod a legjobban megvalósítani a következő fejezetben tárgyalt, igazán okos, költségalapú korlátozást.

A korlátozás alapja: Lépj túl az IP-címen!

Mi alapján azonosítod a „felhasználót”, akire a limitet alkalmazod?

  • IP-cím: A legegyszerűbb, de a legkönnyebben kijátszható. Egy elosztott (DDoS) támadásnál a kérések több ezer IP-címről érkeznek, így az IP-alapú korlátozás hatástalan. Legitim felhasználókat is sújthat, akik egy nagy céges hálózat vagy egyetemi kampusz (NAT) mögül érkeznek.
  • API Kulcs: Sokkal jobb. Minden regisztrált fejlesztő vagy kliens kap egy egyedi kulcsot. Ez már lehetővé teszi a felhasználónkénti korlátozást. De mi van, ha egy támadó több száz kulcsot regisztrál?
  • Felhasználói azonosító (User ID): Ha a felhasználóidnak be kell jelentkezniük, ez a legjobb megoldás. A korlátozást a bejelentkezett felhasználóhoz kötöd, nem egy absztrakt kulcshoz.

De még ez sem elég egy AI modellhez.

Egy AI API esetében nem a kérések számát kell korlátoznod, hanem a felhasznált számítási kapacitást.

Gondolj vissza a Michelin-csillagos étteremre. Az a helyes stratégia, hogy óránként csak 20 vendéget engedsz be? Nem. Mert lehet, hogy az a 20 vendég mind a legdrágább, 10 fogásos degusztációs menüt rendeli, ami teljesen leterheli a konyhát. A helyes stratégia az, hogy a konyha kapacitását korlátozod. Óránként mondjuk 50 „fogást” tudnak elkészíteni. Egy saláta 1 „fogás”, a degusztációs menü 10.

Ezt kell tenned a te API-ddal is. Vezess be egy „számítási egység” (compute unit) fogalmat. Minden API végpontnak legyen egy súlya:

API Végpont Leírás Költség (Számítási Egység)
GET /api/v1/status Rendszer állapotának ellenőrzése. 1
POST /api/v1/summarize Rövid szöveg összefoglalása. 10
POST /api/v1/chat Chatbot interakció (a kért válasz hossza alapján). 5 + (0.1 * max_tokens)
POST /api/v1/generate_image Képgenerálás (a felbontástól függően). 100 (SD) / 500 (HD)

Ezután a Token Bucket algoritmust már nem a kérések számára, hanem a felhasznált számítási egységekre alkalmazod. Minden felhasználó kap percenként mondjuk 1000 „számítási tokent”. Ebből vagy csinál 1000 status checket, vagy 100 összefoglalást, vagy két HD képet. Így a korlátozásod arányban áll a valós költségekkel. Ez a kulcs a Denial of Wallet támadások kivédéséhez.

A Red Teamer nézőpontja: Hogyan játszanám ki a védelmedet?

Oké, beállítottad a szuper, költségalapú Token Bucket rendszeredet. Biztonságban vagy? Dehogy. Most jön a móka. Red Teamerként az a dolgom, hogy megtaláljam a logikádban a réseket.

A „Slow Drip” támadás

A legtöbb rate limiter a rövid, intenzív tüskék ellen véd. De mi van, ha nem egy cunami jön, hanem egy lassan, de folyamatosan emelkedő vízszint? A „Slow Drip” vagy „Low-and-Slow” támadás lényege, hogy a támadó a kéréseit pont a rate limit alatt tartja, de folyamatosan, hosszú időn keresztül. Egyenként ezek a kérések ártalmatlannak tűnnek, de összességében lassan felemésztik az erőforrásaidat, és más, legitim felhasználóktól veszik el a kapacitást.

Képzeld el, hogy a limited 100 kérés/perc. A támadó percenként 99 kérést küld. Órákon, napokon keresztül. A rate limitered soha nem fog bejelezni. De ha ezek a kérések mind a legdrágább végpontodat célozzák, akkor is óriási kárt okoznak.

A megoldás: Adaptív, viselkedésalapú korlátozás

A statikus limitek ostobák. Nem veszik figyelembe a kontextust. A védelem következő szintje az adaptív rate limiting. A rendszer figyeli minden egyes felhasználó (API kulcs, User ID) viselkedését, és megtanulja, mi a „normális”.

Például, a rendszer látja, hogy „user_123” általában munkaidőben aktív, és óránként 20-30 kérést küld, főleg a /summarize végpontra. Ha ugyanez a felhasználó hirtelen vasárnap hajnali 3-kor elkezd percenként 90 kérést küldeni a /generate_image végpontra, az gyanús. Még ha a globális limit alatt is van, a rendszer anomáliát észlel, és ideiglenesen egy sokkal szigorúbb limitet alkalmaz erre a felhasználóra, vagy akár riasztást küld.

Ez már nem egy egyszerű kidobóember egy számlálóval. Ez egy tapasztalt biztonsági őr, aki felismeri a gyanús viselkedést. Látja, ha valaki túl sokáig nézelődik a záraknál, vagy ha egy vendég hirtelen elkezd furcsán viselkedni.

Statikus vs. Adaptív Rate Limiting Idő Kérések/perc Statikus Limit (100) Adaptív Limit (megtanult viselkedés) Normál forgalom „Slow Drip” Támadás Észrevétlen támadás (Statikus limit alatt) A statikus limit nem észleli a normál szintet meghaladó, de a küszöb alatti támadást. Az adaptív, viselkedésalapú limit viszont igen.

Konklúzió: Ne csak őrt állíts, képezd is ki!

Az AI API-d védelme nem egy egyszeri feladat, amit kipipálhatsz a listádon. Ez egy folyamatos macska-egér játék. A támadók egyre okosabbak, a te védelmednek is annak kell lennie.

Elkezdeni egyszerű. Implementálj egy Token Bucket alapú rate limitert az API Gateway szintjén. Korlátozz API kulcs vagy felhasználói azonosító alapján. Ez már több, mint a semmi. Megvéd a legegyszerűbb, legostobább támadásoktól.

De ne állj meg itt. A következő lépés, ami elválasztja a profikat az amatőröktől, a költségalapú korlátozás bevezetése. Kezeld a számítási kapacitást a legértékesebb erőforrásodként, és árazd be a kéréseket ennek megfelelően. Ez az, ami megvéd a pénzügyi katasztrófától.

És végül, gondolkodj úgy, mint egy támadó. Ne bízz a statikus szabályokban. Fektess be viselkedésalapú, adaptív rendszerekbe, amelyek tanulnak és alkalmazkodnak. A te digitális kidobód ne csak egy számlálót bámuljon, hanem figyelje a tömeget, és ismerje fel a bajt, mielőtt az megtörténik.

Szóval tedd fel magadnak újra a kérdést, de most őszintén. A te rendszered készen áll a viharra, vagy csak reménykedsz, hogy ma éjjel nem lesz balhé?