Cookie-k és szerveroldali munkamenetek
Célok
A lecke végére le tudod írni, hogyan működik a cookie (Set-Cookie, Cookie), meg tudod különböztetni a cookie-t a munkamenettől, ismered a fő cookie-attribútumokat (Secure, HttpOnly, SameSite, Max-Age), és érted, miért kell a kijelentkezést szerveroldalon is megvalósítani.
Miért kell a cookie?
Az előző lecke szerint a szervernek azonosítóra van szüksége ahhoz, hogy a kéréseket egy felhasználóhoz kösse. De honnan jusson az azonosító minden kéréshez? A felhasználó nem fogja minden kattintásnál megadni. A cookie (süti) ezt automatizálja: a szerver egy kis adatot küld, a böngésző eltárolja, és a megfelelő későbbi kérésekhez magától csatolja. Az MDN szerint a cookie-k három fő célra szolgálnak: munkamenet-kezelésre (bejelentkezés, kosár), személyre szabásra (nyelv, téma) és követésre.
Bejelentkezés után új kérés
A hallgató belép a Kurzuspontba. A szerver ellenőrzi a belépést, létrehoz egy munkamenetet, és a válasz Set-Cookie fejlécében azonosítót küld. Egy későbbi kérésnél a böngésző ezt Cookie kérésfejlécben továbbítja. A kipróbáló szerver tényleges válasza és a következő kérés (a curl cookie-tárolóval):
$ curl -i -c jar.txt -X POST http://localhost:8085/login -d '{"nev":"anna","jelszo":"titok1"}'
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: sid=b8734e2e4960707a816d559c00663b42; Path=/; HttpOnly; SameSite=Lax; Max-Age=3600
$ curl -v -b jar.txt http://localhost:8085/jelentkezesek/anna
> GET /jelentkezesek/anna HTTP/1.1
> Cookie: sid=b8734e2e4960707a816d559c00663b42
< HTTP/1.1 200 OK
["webprog"]
sequenceDiagram
participant B as Böngésző
participant S as Szerver
B->>S: Belépési kérés (név, jelszó)
S-->>B: Set-Cookie: sid=azonosító
B->>S: Kurzusok kérése + Cookie: sid=azonosító
S-->>B: Személyre szabott válasz
A cookie-ban célszerű csak a szükséges, véletlenszerű azonosítót tartani, a részletes munkamenetállapotot a szerver kezeli. Az MDN is azt tanácsolja, hogy ne tegyünk érzékeny adatot közvetlenül a cookie-ba, hanem átláthatatlan munkamenet-azonosítót használjunk, amelyet a szerver keres meg.
Cookie és munkamenet különbsége
- A cookie a böngésző és a szerver közötti továbbítás eszköze.
- A munkamenet (session) az alkalmazás által szerveroldalon kezelt állapot, amelyet az azonosítóval keresünk meg.
Következmények: ha a szerver érvényteleníti a munkamenetet, a böngészőben maradó régi azonosító nem ad újra hozzáférést. Ha a böngésző elveszíti a cookie-t, a szerver nem tudja ugyanazzal az azonosítóval összekapcsolni a következő kérést. A cookie más célra is használható (nyelvi beállítás), de nem való nagy vagy összetett helyi adat tárolására: az MDN szerint a böngészők a cookie méretét általában 4 kilobájtra korlátozzák, a cookie pedig minden egyező kéréssel elmegy, ami lassíthatja a kapcsolatot. Helyi adathoz a Web Storage vagy az IndexedDB való.
A cookie hatóköre és attribútumai
A Set-Cookie fejléc a névérték-pár mellett attribútumokat is tartalmazhat. Az MDN leírása szerint:
| Attribútum |
Mit tesz? |
Domain |
Melyik domainre és aldomainjeire küldhető. Ha nincs megadva, csak az eredeti hosztnak. |
Path |
Csak a megfelelő útvonalú kéréshez küldi a böngésző (nem biztonsági határ). |
Expires / Max-Age |
Meddig él. Ha egyik sincs, munkamenet-cookie: a böngésző bezárásakor törlődik. A Max-Age elsőbbséget élvez. |
Secure |
Csak https: kéréshez küldi (a localhost kivétel). |
HttpOnly |
A JavaScript nem olvashatja (document.cookie), de a böngésző a kérésekhez csatolja. Az XSS ellen véd (8. fejezet). |
SameSite |
A más webhelyről induló kérésekhez kapcsolódó küldést szabályozza. |
A SameSite értékei az MDN szerint:
Strict: csak azonos webhelyről induló kéréshez küldi;
Lax: azonos webhelyre, továbbá a más webhelyről indított, „felső szintű” navigációhoz (például egy linkre kattintás) biztonságos metódusokkal. Az MDN süti-útmutatója szerint ez az alapértelmezés, ha az attribútum hiányzik;
None: minden kérésnél küldi, de Secure kell hozzá.
A SameSite a CSRF (Cross-Site Request Forgery) ellen véd, amelyet a 8. fejezet tárgyal: a támadó oldal elindít egy kérést a Kurzuspont felé, és a böngésző a cookie-t magától csatolná. Az Strict és Lax ezt akadályozza.
További védelem a névelőtag: egy __Host- előtagú cookie csak Secure-ral, Path=/ útvonallal és Domain nélkül állítható be, így az pontosan az adott hoszthoz kötött. A kiszolgálónak az előtaggal együtt kell ellenőriznie a nevet.
Harmadik fél cookie-ja és adatvédelem
A harmadik fél cookie-ja olyan beágyazott tartalomhoz (például egy iframe-hez vagy hirdetéshez) tartozik, amely más webhelyről érkezik, és oldalak közötti követést is lehetővé tesz. Az MDN szerint a böngészők egyre inkább alapértelmezésben blokkolják őket. A GDPR (General Data Protection Regulation) és az ePrivacy irányelv nyilvánosságot és beleegyezést kér a nem szükséges cookie-k használatához. Ezt a kérdést az adatvédelemről szóló 9.6 lecke részletezi.
Életciklus és kijelentkezés
A munkamenet nem tarthat örökké. Lejárhat, a felhasználó kijelentkezhet, a szerver biztonsági okból megszüntetheti. A kijelentkezésnek ezért a szerveroldali hozzáférést is érvénytelenítenie kell, nem elég a felületet „belépés nélkülinek” mutatni. A kipróbáló szerveren a kijelentkezés után ugyanazzal az azonosítóval küldött kérés elutasításra kerül:
$ curl -i -b jar.txt -X POST http://localhost:8085/logout
HTTP/1.1 204 No Content
Set-Cookie: sid=; Path=/; Max-Age=0
$ curl -i -H "Cookie: sid=b8734e2e4960707a816d559c00663b42" http://localhost:8085/jelentkezesek/anna
HTTP/1.1 401 Unauthorized
{"hiba":"nincs bejelentkezve"}
A Max-Age=0 a böngésző oldali cookie-t törli. Az igazán fontos viszont a második kérés: a szerver már nem ismeri az azonosítót, ezért a régi cookie másolata sem használható. Ha a kijelentkezés csak a böngészőt „tisztítaná meg”, egy korábban megszerzett azonosítóval tovább lehetne dolgozni.
Az MDN két további tanácsot ad a munkamenetekhez: a munkamenet-azonosítót be- vagy átlépéskor újra kell generálni (a session fixation támadás ellen), és az érzékeny cookie-k élettartama legyen rövid.
Végigvezetett példa: a Kurzuspont belépési cookie-ja
| Beállítás |
Érték |
Indok |
| Név |
__Host-sid |
A hoszthoz kötött, Secure, Path=/. |
| Érték |
128 bites véletlen |
Nem találgatható, nem hordoz adatot. |
HttpOnly |
igen |
A kliensprogram (és egy beszúrt idegen szkript) ne olvashassa. |
Secure |
igen |
Csak HTTPS-en megy (4.3). |
SameSite |
Lax |
Védi a más oldalról indított kéréseket; a linkről érkezés még működik. |
Max-Age |
3600 |
Egy óra; rövid élettartam. |
| Kijelentkezés |
A szerver törli a munkamenetet |
A régi azonosító nem használható. |
(A kipróbáló szerver egyszerűsített, a Secure és a __Host- névelőtag nélkül fut, mert a példa HTTP-n, localhost-on megy.)
Gyakori tévhitek
| Állítás |
Pontosítás |
| „A cookie maga a teljes munkamenet.” |
Gyakran csak az azonosítót hordozza; az állapotot a szerver kezeli. |
| „A böngésző minden cookie-t minden kéréshez elküld.” |
A hatókör és az attribútumok korlátozzák a küldést. |
| „A kijelentkezés csak a gomb feliratának cseréje.” |
A szerveroldali hozzáférést is meg kell szüntetni. |
| „Minden helyi adatot cookie-ban kell tárolni.” |
A Web Storage és az IndexedDB más célra alkalmasabb. |
„A HttpOnly mindenre véd.” |
Az XSS-hez kapcsolódó olvasást korlátozza, de a kérések csatolását nem. |
Röviden
- A cookie a szerver által küldött, a böngésző által tárolt és csatolt kis adat; a munkamenet a szerver oldali állapot.
- A munkamenet-cookie legyen
HttpOnly, Secure, SameSite, rövid életű, véletlen azonosítóval.
- A kijelentkezésnek a szerveroldali munkamenetet is meg kell szüntetnie.
- Harmadik fél cookie-ját követésre használhatják; ezért szabályozott.
Ellenőrző kérdések
- Melyik fejléc küldi a cookie-t a szervertől a böngészőnek, és melyik vissza?
- Mit jelent a
HttpOnly, a Secure és a SameSite?
- Miért nem elég a kijelentkezéskor csak a böngészőből törölni a cookie-t?
- Miért nem jó helyi adat tárolására a cookie?
Tanulási források
Cookie-k és szerveroldali munkamenetek
Célok
A lecke végére le tudod írni, hogyan működik a cookie (
Set-Cookie,Cookie), meg tudod különböztetni a cookie-t a munkamenettől, ismered a fő cookie-attribútumokat (Secure,HttpOnly,SameSite,Max-Age), és érted, miért kell a kijelentkezést szerveroldalon is megvalósítani.Miért kell a cookie?
Az előző lecke szerint a szervernek azonosítóra van szüksége ahhoz, hogy a kéréseket egy felhasználóhoz kösse. De honnan jusson az azonosító minden kéréshez? A felhasználó nem fogja minden kattintásnál megadni. A cookie (süti) ezt automatizálja: a szerver egy kis adatot küld, a böngésző eltárolja, és a megfelelő későbbi kérésekhez magától csatolja. Az MDN szerint a cookie-k három fő célra szolgálnak: munkamenet-kezelésre (bejelentkezés, kosár), személyre szabásra (nyelv, téma) és követésre.
Bejelentkezés után új kérés
A hallgató belép a Kurzuspontba. A szerver ellenőrzi a belépést, létrehoz egy munkamenetet, és a válasz
Set-Cookiefejlécében azonosítót küld. Egy későbbi kérésnél a böngésző eztCookiekérésfejlécben továbbítja. A kipróbáló szerver tényleges válasza és a következő kérés (acurlcookie-tárolóval):sequenceDiagram participant B as Böngésző participant S as Szerver B->>S: Belépési kérés (név, jelszó) S-->>B: Set-Cookie: sid=azonosító B->>S: Kurzusok kérése + Cookie: sid=azonosító S-->>B: Személyre szabott válaszA cookie-ban célszerű csak a szükséges, véletlenszerű azonosítót tartani, a részletes munkamenetállapotot a szerver kezeli. Az MDN is azt tanácsolja, hogy ne tegyünk érzékeny adatot közvetlenül a cookie-ba, hanem átláthatatlan munkamenet-azonosítót használjunk, amelyet a szerver keres meg.
Cookie és munkamenet különbsége
Következmények: ha a szerver érvényteleníti a munkamenetet, a böngészőben maradó régi azonosító nem ad újra hozzáférést. Ha a böngésző elveszíti a cookie-t, a szerver nem tudja ugyanazzal az azonosítóval összekapcsolni a következő kérést. A cookie más célra is használható (nyelvi beállítás), de nem való nagy vagy összetett helyi adat tárolására: az MDN szerint a böngészők a cookie méretét általában 4 kilobájtra korlátozzák, a cookie pedig minden egyező kéréssel elmegy, ami lassíthatja a kapcsolatot. Helyi adathoz a Web Storage vagy az IndexedDB való.
A cookie hatóköre és attribútumai
A
Set-Cookiefejléc a névérték-pár mellett attribútumokat is tartalmazhat. Az MDN leírása szerint:DomainPathExpires/Max-AgeMax-Ageelsőbbséget élvez.Securehttps:kéréshez küldi (alocalhostkivétel).HttpOnlydocument.cookie), de a böngésző a kérésekhez csatolja. Az XSS ellen véd (8. fejezet).SameSiteA
SameSiteértékei az MDN szerint:Strict: csak azonos webhelyről induló kéréshez küldi;Lax: azonos webhelyre, továbbá a más webhelyről indított, „felső szintű” navigációhoz (például egy linkre kattintás) biztonságos metódusokkal. Az MDN süti-útmutatója szerint ez az alapértelmezés, ha az attribútum hiányzik;None: minden kérésnél küldi, deSecurekell hozzá.A
SameSitea CSRF (Cross-Site Request Forgery) ellen véd, amelyet a 8. fejezet tárgyal: a támadó oldal elindít egy kérést a Kurzuspont felé, és a böngésző a cookie-t magától csatolná. AzStrictésLaxezt akadályozza.További védelem a névelőtag: egy
__Host-előtagú cookie csakSecure-ral,Path=/útvonallal ésDomainnélkül állítható be, így az pontosan az adott hoszthoz kötött. A kiszolgálónak az előtaggal együtt kell ellenőriznie a nevet.Harmadik fél cookie-ja és adatvédelem
A harmadik fél cookie-ja olyan beágyazott tartalomhoz (például egy
iframe-hez vagy hirdetéshez) tartozik, amely más webhelyről érkezik, és oldalak közötti követést is lehetővé tesz. Az MDN szerint a böngészők egyre inkább alapértelmezésben blokkolják őket. A GDPR (General Data Protection Regulation) és az ePrivacy irányelv nyilvánosságot és beleegyezést kér a nem szükséges cookie-k használatához. Ezt a kérdést az adatvédelemről szóló 9.6 lecke részletezi.Életciklus és kijelentkezés
A munkamenet nem tarthat örökké. Lejárhat, a felhasználó kijelentkezhet, a szerver biztonsági okból megszüntetheti. A kijelentkezésnek ezért a szerveroldali hozzáférést is érvénytelenítenie kell, nem elég a felületet „belépés nélkülinek” mutatni. A kipróbáló szerveren a kijelentkezés után ugyanazzal az azonosítóval küldött kérés elutasításra kerül:
A
Max-Age=0a böngésző oldali cookie-t törli. Az igazán fontos viszont a második kérés: a szerver már nem ismeri az azonosítót, ezért a régi cookie másolata sem használható. Ha a kijelentkezés csak a böngészőt „tisztítaná meg”, egy korábban megszerzett azonosítóval tovább lehetne dolgozni.Az MDN két további tanácsot ad a munkamenetekhez: a munkamenet-azonosítót be- vagy átlépéskor újra kell generálni (a session fixation támadás ellen), és az érzékeny cookie-k élettartama legyen rövid.
Végigvezetett példa: a Kurzuspont belépési cookie-ja
__Host-sidSecure,Path=/.HttpOnlySecureSameSiteLaxMax-Age(A kipróbáló szerver egyszerűsített, a
Secureés a__Host-névelőtag nélkül fut, mert a példa HTTP-n,localhost-on megy.)Gyakori tévhitek
HttpOnlymindenre véd.”Röviden
HttpOnly,Secure,SameSite, rövid életű, véletlen azonosítóval.Ellenőrző kérdések
HttpOnly, aSecureés aSameSite?Tanulási források