A lecke végére el tudod magyarázni a CSRF működését, tudod, mely feltételek mellett lehetséges, és meg tudod nevezni a védelmeit: CSRF-token, Fetch metadata, nem egyszerű kérések, SameSite cookie, Origin ellenőrzése.
Miért működhet egy idegen oldalról érkező kérés?
A hallgató be van jelentkezve a Kurzuspontba, majd megnyit egy idegen weboldalt. Az idegen oldal egy rejtett űrlapot küldhet el a Kurzuspont címére (POST /lemondas). A böngésző a cookie-kat a kérés célja szerint csatolja (7.2), ezért a kérés a bejelentkezett munkamenettel érkezik. Ha a Kurzuspont szervere csak a cookie meglétét vizsgálja, a kérést a hallgató szándékának tekinti. Ez a CSRF. Az MDN szerint akkor lehetséges, ha az oldal HTTP-kérésekkel változtat állapotot, kizárólag cookie-ra támaszkodik a hitelesítésben, és olyan paramétereket használ, amelyeket a támadó előre ki tud találni. A támadónak nem kell elolvasnia a választ: a mellékhatás a lényeg (8.2).
sequenceDiagram
participant H as Hallgató
participant I as Idegen oldal
participant B as Böngésző
participant K as Kurzus API
H->>B: Bejelentkezett munkamenet
B->>I: Idegen oldal megnyitása
I->>B: Állapotváltoztató kérés kiváltása
B->>K: Kérés + cookie
K-->>B: Művelet eredménye
Kipróbálva: ugyanaz a kérés három szerveren
Egy kipróbáló szerver három változatának ugyanazt a kérést küldtük, amit egy idegen oldalról kiváltott böngészői kérés jelentene: a hallgató cookie-ját és az Origin: https://idegen.example, Sec-Fetch-Site: cross-site fejlécet (ezeket a böngésző küldi, a curl itt utánozza). A második kérés a Kurzuspont saját oldaláról érkezik, a megfelelő jelzésekkel.
Védelem a szerveren
Idegen oldalról
Saját oldalról
Nincs (csak a cookie-t nézi)
200: „a jelentkezés lemondva anna nevében”
200
CSRF-token (X-CSRF-Token)
403: „hiányzó vagy hibás CSRF-token”
200 (a token az űrlap lekérésekor érkezett)
Fetch metadata (Sec-Fetch-Site)
403: „idegen eredetű kérés”
200
A védelem nélküli szerver az idegen oldalról érkező kérést is elfogadta, és Anna nevében lemondta a jelentkezést. A másik két szerver elutasította.
A védelmek
Az MDN összefoglalója szerint:
CSRF-token (elsődleges védelem). A szerver egy kiszámíthatatlan tokent ágyaz az oldalba (űrlapnál rejtett mező, fetch()-nél fejléc), és minden állapotváltoztató kérésnél ellenőrzi. Az idegen oldal nem ismeri a tokent, mert (8.2) nem olvashatja el a Kurzuspont oldalát.
Fetch metadata (elsődleges védelem). A böngésző minden kéréshez Sec-Fetch-Site fejlécet küld, amely megmondja, a kérés same-origin, same-site, cross-site vagy none (a felhasználó közvetlen műveletéből ered). A szerver elutasíthatja a cross-site állapotváltoztató kéréseket.
Nem egyszerű kérések használata (JavaScript-API-knál). Az egyszerű kéréseket (például űrlapküldés) idegen eredetről is el lehet küldeni; a nem egyszerűek (például Content-Type: application/json vagy egyedi fejléc) előbb preflightot igényelnek (8.2), amelyet az idegen eredet nem kap meg. Ezzel csak akkor érdemes védekezni, ha a CORS-beállítás nem engedi a támadó eredetét.
SameSite cookie (mélységi védelem). Strict: idegen webhelyről sosem küldi; Lax: csak biztonságos metódusú, felső szintű navigációnál. Az MDN szerint ha lehet, Strict, különben Lax. A SameSite webhelyszinten (site), nem eredetszinten dolgozik, így az összes aldomainnek megbízhatónak kell lennie.
Origin (és Referer) ellenőrzése. A szerver elutasíthatja azokat az állapotváltoztató kéréseket, amelyek Origin fejléce nem a saját eredete.
És az alapszabály: állapotot ne változtass GET-tel (2.3). Egy GET kérést egy <img src=...> is kiválthat, és a Lax cookie-t felső szintű GET navigáció is elküldi.
Ha az alkalmazás XSS-sérülékeny (8.3), a támadó a saját eredetből indít kérést, így a CSRF-védelmek egy részét megkerülheti. A védelmi rétegek tehát egymásra épülnek.
Végigvezetett példa: a Kurzuspont lemondás művelete
Döntés
Indok
A lemondás DELETE vagy POST, soha nem GET
A GET bárhonnan kiváltható (2.3).
A munkamenet-cookie HttpOnly; Secure; SameSite=Lax
Alapvédelem az idegen oldalról érkező kérések ellen (7.2).
Az űrlap CSRF-tokent kap, a szerver ellenőrzi
Elsődleges védelem.
A szerver ellenőrzi a Sec-Fetch-Site és az Origin fejlécet
Mélységi védelem.
Az API JSON-t vár Content-Type: application/json fejléccel
Nem egyszerű kérés, preflight kell.
Gyakori tévhitek
Állítás
Pontosítás
„A CORS megakadályozza a CSRF-et.”
A CORS főként a válasz olvasását szabályozza.
„Ha a kérés POST, nem lehet CSRF.”
Az idegen oldal űrlapja POST kérést is elküldhet.
„A SameSite teljesen megoldja.”
Mélységi védelem; webhelyszinten dolgozik, és a tokent nem pótolja teljesen.
„A CSRF-hez el kell olvasni a választ.”
A mellékhatás elég.
„A HTTPS megvéd.”
A kapcsolatot védi, nem a kérés szándékát (4.3).
Röviden
CSRF: egy idegen oldal a bejelentkezett böngésző cookie-jával kényszerít ki állapotváltozást.
Feltételek: állapotváltoztató HTTP-kérés, csak cookie alapú hitelesítés, kitalálható paraméterek.
Védelem: CSRF-token, Fetch metadata, nem egyszerű kérések, SameSite cookie, Origin ellenőrzése.
Állapotot ne változtass GET-tel; a CORS nem CSRF-védelem.
Ellenőrző kérdések
Miért csatolja a böngésző a cookie-t az idegen oldalról indított kéréshez?
Miért nem tudja egy idegen oldal kitalálni a CSRF-tokent?
CSRF: kérés idegen oldal hatására
Célok
A lecke végére el tudod magyarázni a CSRF működését, tudod, mely feltételek mellett lehetséges, és meg tudod nevezni a védelmeit: CSRF-token, Fetch metadata, nem egyszerű kérések,
SameSitecookie,Originellenőrzése.Miért működhet egy idegen oldalról érkező kérés?
A hallgató be van jelentkezve a Kurzuspontba, majd megnyit egy idegen weboldalt. Az idegen oldal egy rejtett űrlapot küldhet el a Kurzuspont címére (
POST /lemondas). A böngésző a cookie-kat a kérés célja szerint csatolja (7.2), ezért a kérés a bejelentkezett munkamenettel érkezik. Ha a Kurzuspont szervere csak a cookie meglétét vizsgálja, a kérést a hallgató szándékának tekinti. Ez a CSRF. Az MDN szerint akkor lehetséges, ha az oldal HTTP-kérésekkel változtat állapotot, kizárólag cookie-ra támaszkodik a hitelesítésben, és olyan paramétereket használ, amelyeket a támadó előre ki tud találni. A támadónak nem kell elolvasnia a választ: a mellékhatás a lényeg (8.2).sequenceDiagram participant H as Hallgató participant I as Idegen oldal participant B as Böngésző participant K as Kurzus API H->>B: Bejelentkezett munkamenet B->>I: Idegen oldal megnyitása I->>B: Állapotváltoztató kérés kiváltása B->>K: Kérés + cookie K-->>B: Művelet eredményeKipróbálva: ugyanaz a kérés három szerveren
Egy kipróbáló szerver három változatának ugyanazt a kérést küldtük, amit egy idegen oldalról kiváltott böngészői kérés jelentene: a hallgató cookie-ját és az
Origin: https://idegen.example,Sec-Fetch-Site: cross-sitefejlécet (ezeket a böngésző küldi, acurlitt utánozza). A második kérés a Kurzuspont saját oldaláról érkezik, a megfelelő jelzésekkel.200: „a jelentkezés lemondva anna nevében”200X-CSRF-Token)403: „hiányzó vagy hibás CSRF-token”200(a token az űrlap lekérésekor érkezett)Sec-Fetch-Site)403: „idegen eredetű kérés”200A védelem nélküli szerver az idegen oldalról érkező kérést is elfogadta, és Anna nevében lemondta a jelentkezést. A másik két szerver elutasította.
A védelmek
Az MDN összefoglalója szerint:
fetch()-nél fejléc), és minden állapotváltoztató kérésnél ellenőrzi. Az idegen oldal nem ismeri a tokent, mert (8.2) nem olvashatja el a Kurzuspont oldalát.Sec-Fetch-Sitefejlécet küld, amely megmondja, a kéréssame-origin,same-site,cross-sitevagynone(a felhasználó közvetlen műveletéből ered). A szerver elutasíthatja across-siteállapotváltoztató kéréseket.Content-Type: application/jsonvagy egyedi fejléc) előbb preflightot igényelnek (8.2), amelyet az idegen eredet nem kap meg. Ezzel csak akkor érdemes védekezni, ha a CORS-beállítás nem engedi a támadó eredetét.SameSitecookie (mélységi védelem).Strict: idegen webhelyről sosem küldi;Lax: csak biztonságos metódusú, felső szintű navigációnál. Az MDN szerint ha lehet,Strict, különbenLax. ASameSitewebhelyszinten (site), nem eredetszinten dolgozik, így az összes aldomainnek megbízhatónak kell lennie.Origin(ésReferer) ellenőrzése. A szerver elutasíthatja azokat az állapotváltoztató kéréseket, amelyekOriginfejléce nem a saját eredete.És az alapszabály: állapotot ne változtass
GET-tel (2.3). EgyGETkérést egy<img src=...>is kiválthat, és aLaxcookie-t felső szintűGETnavigáció is elküldi.Ha az alkalmazás XSS-sérülékeny (8.3), a támadó a saját eredetből indít kérést, így a CSRF-védelmek egy részét megkerülheti. A védelmi rétegek tehát egymásra épülnek.
Végigvezetett példa: a Kurzuspont lemondás művelete
DELETEvagyPOST, soha nemGETGETbárhonnan kiváltható (2.3).HttpOnly; Secure; SameSite=LaxSec-Fetch-Siteés azOriginfejlécetContent-Type: application/jsonfejléccelGyakori tévhitek
SameSiteteljesen megoldja.”Röviden
SameSitecookie,Originellenőrzése.GET-tel; a CORS nem CSRF-védelem.Ellenőrző kérdések
Sec-Fetch-Site: cross-sitefejléc?SameSitecookie egyedül?Tanulási források
SameSiteattribútum.