Skip to content
Language:hu Author:Laborci Gergely
identity

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.

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.

  • 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 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.

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.

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

  1. Melyik fejléc küldi a cookie-t a szervertől a böngészőnek, és melyik vissza?
  2. Mit jelent a HttpOnly, a Secure és a SameSite?
  3. Miért nem elég a kijelentkezéskor csak a böngészőből törölni a cookie-t?
  4. Miért nem jó helyi adat tárolására a cookie?

Tanulási források

Prerequisites (2)

  • HTTP
  • alkalmazásállapot

Teaches (2)

  • cookie
  • munkamenet