Çərəzlər (Cookies): Veb Tətbiqlərinin Əvəzolunmaz Yaddaşı
Salamlar, Keçən dəfə HTTP-nin "vətəndaşlığı olmayan" (stateless) təbiətindən danışmışdıq. Bəs bu yaddaşsız protokolla necə olur ki, veb saytlar bizi "tanıyır", login statusumuzu saxlayır, alış-veriş səbətimiz boş qalmır? Cavab çox vaxt kiçik mətn fayllarında gizlənir: Cookies. Bu gün biz bu kiçik, amma qüdrətli köməkçilərin dərinliklərinə baş vuracağıq – necə yarandığından tutmuş, təhlükəsizlik risklərinə və müasir alternativlərinə qədər. Hazırsınızsa, cookie jar-ı açaq!
HTTP Çərəzlərinin Quruluşu: Set-Cookie Başlığı və Parametrləri
Bir cookie-nin həyatı serverin göndərdiyi HTTP response başlığı ilə başlayır: Set-Cookie
. Brauzer bu başlığı gördükdə, içindəki direktivlərə əsasən cookie-ni yadda saxlayır və gələcək uyğun istəklərdə (Cookie
başlığı ilə) serverə geri göndərir.
Tipik bir Set-Cookie başlığı belə görünə bilər:
Gəlin bu direktivləri (parametrləri) detallı şəkildə analiz edək:
- Name=Value: Cookie-nin əsas yükü.
sessionId=a3fWa
hissəsi cookie-nin adını (sessionId) və dəyərini (a3fWa) göstərir. Bu, serverin istifadəçini və ya onun vəziyyətini tanıması üçün istifadə etdiyi məlumatdır. - Expires=Date: Cookie-nin son istifadə tarixini göstərir. Bu tarixdən sonra brauzer cookie-ni avtomatik silir. Formatı spesifikdir (RFC 6265). Əgər Expires və Max-Age təyin edilməyibsə, bu bir session cookie olur və brauzer sessiyası (adətən brauzer pəncərəsi) bağlananda silinir.
- Max-Age=Seconds: Cookie-nin neçə saniyə yaşayacağını göstərir. Expires-dən daha müasirdir və ona nəzərən üstünlüyə malikdir (əgər hər ikisi təyin edilibsə). Mənfi dəyər cookie-ni dərhal silir. Məsələn,
Max-Age=3600
cookie-nin 1 saat yaşayacağını bildirir. - Domain=domain.name: Cookie-nin hansı domen(lər)ə göndəriləcəyini təyin edir. Əgər təyin edilməzsə, yalnız cookie-ni təyin edən serverin domen adı (originating host) üçün keçərli olur.
.
ilə başlayan dəyər (məs:.example.com
) həm əsas domen, həm də onun bütün subdomain-ləri (məs:www.example.com
,api.example.com
) üçün keçərli olmasını təmin edir. - Path=path: Cookie-nin hansı URL path-ları üçün göndəriləcəyini məhdudlaşdırır. Əgər
/
təyin edilibsə, bütün path-lar üçün göndərilir. Əgər/app
təyin edilibsə, yalnız/app
və onun altındakı path-lar (/app/profile
,/app/settings
) üçün göndərilir. - 🛡️ Secure: Bu flag təyin edildikdə, brauzer cookie-ni yalnız HTTPS bağlantısı üzərindən göndərir. HTTP üzərindən göndərilməsinin qarşısını alaraq man-in-the-middle hücumlarında cookie-nin oğurlanma riskini azaldır. Mütləq istifadə olunmalıdır!
- 🛡️ HttpOnly: Bu flag təyin edildikdə, cookie-yə JavaScript vasitəsilə (
document.cookie
API) müraciət etmək mümkün olmur. Bu, Cross-Site Scripting (XSS) hücumları nəticəsində session cookie-lərinin oğurlanmasının qarşısını almaq üçün ən vacib təhlükəsizlik tədbirlərindən biridir. - 🛡️ SameSite=Strict | Lax | None: Cross-Site Request Forgery (CSRF) hücumlarına qarşı müdafiəni gücləndirir. Cookie-nin cross-site (fərqli saytdan gələn) istəklərlə birlikdə göndərilib-göndərilməyəcəyini idarə edir:
- Strict: Cookie yalnız eyni saytdan (same-site) gələn istəklərlə göndərilir. Başqa saytdakı linkə klikləyərək gəlsəniz belə, cookie göndərilmir. Ən təhlükəsizdir, amma bəzən istifadəçi təcrübəsini poza bilər.
- Lax: Standart dəyər (əksər müasir brauzerlərdə). Cookie eyni saytdan gələn istəklərlə VƏ başqa saytdan gələn top-level navigation (GET istəyi, məsələn linkə klikləmə) ilə göndərilir. POST, PUT, DELETE kimi cross-site istəklərlə və ya
<iframe>
,<img>
içindəki istəklərlə göndərilmir. CSRF-ə qarşı yaxşı balans təqdim edir. - None: Cookie bütün cross-site istəklərlə göndərilir. Ancaq bu dəyəri istifadə etmək üçün mütləq Secure atributu da təyin edilməlidir. Əsasən third-party kontekstlərdə (məsələn, embedded content) istifadə olunur.
Praktik İstifadə Sahələri: Oturum İdarəetməsi (Session Management) və İstifadəçi Təcrübəsi
Cookie-lərin ən fundamental rolu HTTP-nin yaddaşsızlığını aradan qaldırmaqdır:
- Oturum İdarəetməsi (Session Management):
- İstifadəçi login olduqda, server unikal bir session identifier (session ID) yaradır.
- Bu session ID
Set-Cookie
başlığı ilə brauzerə göndərilir (adətən HttpOnly və Secure flag-ləri ilə). - Brauzer bu cookie-ni saxlayır və eyni domenə edilən hər sonrakı istəkdə
Cookie: sessionId=...
başlığı ilə geri göndərir. - Server bu session ID-ni alır, ona uyğun session məlumatlarını (kimin login olduğu, səlahiyyətləri və s.) server tərəfdəki yaddaşdan (RAM, database, cache) tapır və istifadəçini "tanıyır".
- Nəticə: İstifadəçi hər səhifəyə keçdikdə yenidən login olmaq məcburiyyətində qalmır. Bu, stateful təcrübənin əsasıdır.
- İstifadəçi Təcrübəsi (User Experience) və Fərdiləşdirmə:
- Tercihlərin Saxlanması: Saytın dili, theme (qaranlıq/işıqlı rejim), baxılmış məhsullar kimi istifadəçi seçimlərini yadda saxlamaq üçün istifadə edilə bilər.
- Alış-veriş Səbəti (Shopping Cart): Login olmamış istifadəçilərin belə səbətlərini müvəqqəti olaraq cookie-lərdə saxlamaq mümkündür (baxmayaraq ki, daha mürəkkəb həllər adətən backend sessiyaları və ya
localStorage
istifadə edir). - İzləmə və Analitika (Tracking & Analytics): İstifadəçilərin saytdakı davranışlarını (hansı səhifələrə baxdıqları, nə qədər vaxt keçirdikləri) izləmək üçün istifadə olunur (məs: Google Analytics). Bu, xüsusilə third-party cookies vasitəsilə həyata keçirilir və məhz bu səbəbdən məxfilik narahatlıqları yaradır.
JavaScript ilə Çərəz Əməliyyatları (document.cookie
)
Əgər bir cookie HttpOnly olaraq işarələnməyibsə, ona client-side JavaScript vasitəsilə müraciət etmək mümkündür:
⚠️ Diqqət! document.cookie
API-si bir az yöndəmsizdir. Bütün cookie-ləri bir string kimi qaytarır və onları parse etmək lazımdır. Həmçinin, bir cookie-ni yeniləmək üçün bütün atributlarını yenidən təyin etmək lazımdır. Ən əsası isə, əgər saytınızda XSS zəifliyi varsa, HttpOnly olmayan bütün cookie-lər (o cümlədən JS ilə yazdıqlarınız) oğurlana bilər! Buna görə də həssas məlumatları (session ID, tokenlər) JS-dən əlçatmaz etmək üçün HttpOnly istifadə etmək kritikdir.
Backend İnteqrasiyası: Spring Boot ilə Cookie İşləmləri
Backend tərəfdə (məsələn, Java Spring Boot ilə) cookie-lərlə işləmək daha nəzarətli və təhlükəsizdir.
-
Cookie Oxumaq:
@CookieValue
Annotation: Ən asan yol. Spring avtomatik olaraq istənilən cookie-nin dəyərini metod parametrininə inject edir.
controller/CookieController.java HttpServletRequest
: Bütün cookie-ləri array şəklində əldə etmək üçün.
controller/CookieControllerReadAll.java -
Cookie Yazmaq/Təyin Etmək:
HttpServletResponse.addCookie()
(Ənənəvi):jakarta.servlet.http.Cookie
obyekti yaradıb response-a əlavə etmək.
controller/CookieControllerSetTheme.java ResponseCookie
(Spring 5+ - Müasir): Daha axıcı (fluent) və müasir atributları (xüsusilə SameSite) asanlıqla təyin etməyə imkan verən builder interfeysi təqdim edir.HttpHeaders.SET_COOKIE
başlığı ilə istifadə olunur.
controller/CookieControllerModern.java ⚙️
ResponseCookie
istifadəsi daha aydın kod yazmağa və bütün vacib təhlükəsizlik atributlarını nəzərə almağa kömək edir.
Təhlükəsizlik Radarında: Risklər və Qorunma Yolları
Cookie-lər faydalı olduğu qədər də təhlükə mənbəyi ola bilər. Əsas risklər və müdafiə mexanizmləri:
- XSS (Cross-Site Scripting):
- Risk: Əgər saytınızda XSS zəifliyi varsa, təcavüzkar zərərli JavaScript kodu yeridərək istifadəçinin brauzerində işə sala bilər. Bu kod
document.cookie
vasitəsilə HttpOnly olmayan bütün cookie-ləri (məsələn, session ID) oğurlaya və təcavüzkarın serverinə göndərə bilər. Nəticədə təcavüzkar həmin istifadəçinin sessiyasını ələ keçirə bilər (session hijacking). - 🛡️ Müdafiə: HttpOnly atributunu MÜTLƏQ aktivləşdirin! Bu, JS-nin cookie-yə birbaşa girişini əngəlləyir. Həmçinin, input validation və output encoding kimi standart XSS müdafiə tədbirlərini tətbiq edin.
- Risk: Əgər saytınızda XSS zəifliyi varsa, təcavüzkar zərərli JavaScript kodu yeridərək istifadəçinin brauzerində işə sala bilər. Bu kod
- CSRF (Cross-Site Request Forgery):
- Risk: Brauzerlər cookie-ləri avtomatik olaraq eyni domenə gedən hər istəyə əlavə edir. Təcavüzkar, istifadəçinin login olduğu bir saytda (məs:
bank.com
) onun adından gizli şəkildə əməliyyat aparmaq üçün başqa bir saytda (məs:evil.com
) xüsusi hazırlanmış bir form və ya link yerləşdirə bilər. İstifadəçievil.com
a daxil olub bu linkə kliklədikdə (və ya form avtomatik submit olduqda), brauzerbank.com
a istək göndərərkənbank.com
üçün olan cookie-ləri (session ID daxil) avtomatik əlavə edəcək.bank.com
bu istəyin legitim istifadəçidən gəldiyini düşünərək əməliyyatı (məs: pul köçürmə) icra edə bilər. - 🛡️ Müdafiə: SameSite atributunu Lax (standart) və ya Strict olaraq təyin edin! Bu, cookie-lərin cross-site istəklərlə göndərilməsini məhdudlaşdıraraq CSRF hücumlarının əksəriyyətinin qarşısını alır. Əlavə təhlükəsizlik qatı üçün state-i dəyişən əməliyyatlarda (POST, PUT, DELETE) Anti-CSRF Token mexanizmini tətbiq edin.
- Risk: Brauzerlər cookie-ləri avtomatik olaraq eyni domenə gedən hər istəyə əlavə edir. Təcavüzkar, istifadəçinin login olduğu bir saytda (məs:
- Session Hijacking (Oğurluq) / Fixation (Sabitləmə):
- Risk: Cookie-ləri şəbəkədə (HTTPS istifadə edilməzsə) dinlənilə (sniffing), XSS ilə oğurlana və ya təcavüzkar tərəfindən əvvəlcədən təyin edilmiş bir session ID istifadəçiyə məcbur edilə (fixation) bilər.
- 🛡️ Müdafiə: Həmişə HTTPS istifadə edin (Secure atributu ilə birlikdə)! Bu, sniffing-in qarşısını alır. HttpOnly XSS vasitəsilə oğurluğa qarşıdır. Session fixation-a qarşı isə istifadəçi login olduqdan dərhal sonra yeni bir session ID generate edin və köhnəsini etibarsız sayın.
Brauzer Arenası: 3rd-Party Cookie Qadağaları
Cookie-lər kontekstə görə iki cür olur:
- First-party Cookie: İstifadəçinin birbaşa daxil olduğu domen tərəfindən təyin edilir (məs:
example.com
da gəzərkənexample.com
tərəfindən təyin edilən cookie). - Third-party Cookie: İstifadəçinin daxil olduğu domendən fərqli bir domen tərəfindən təyin edilir. Adətən reklamlar, sosial media widget-ları, analitika xidmətləri kimi embedded contentlər tərəfindən istifadə olunur (məs:
example.com
da gəzərkənadnetwork.com
tərəfindən təyin edilən cookie).
⚠️ Trend: Məxfilik narahatlıqları səbəbilə (xüsusilə saytlararası izləmə - cross-site tracking), əksər müasir brauzerlər (Safari, Firefox başda olmaqla, Chrome da tədricən) third-party cookie-ləri bloklamağa və ya məhdudlaşdırmağa başlayıb. Bu, rəqəmsal reklam və analitika sənayesində ciddi dəyişikliklərə səbəb olur və alternativ texnologiyaların (məs: Google Privacy Sandbox) inkişafını sürətləndirir.
Çərəzlərə Alternativlər: Müasir Yanaşmalar
Cookie-lər hələ də geniş istifadə olunsa da, bəzi ssenarilərdə alternativlər daha uyğun ola bilər:
- JWT (JSON Web Tokens):
- Stateless autentifikasiya üçün populyar seçimdir. Login zamanı server imzalanmış bir token yaradır və client-ə göndərir.
- Client bu token-i adətən
localStorage
və yasessionStorage
da saxlayır və hər qorunan istəkdəAuthorization: Bearer <token>
başlığı ilə göndərir. - Serverin session məlumatlarını saxlamasına ehtiyac qalmır (ona görə stateless).
- Müqayisə: Cookie-lərə nəzərən CSRF-ə qarşı təbii olaraq daha davamlıdır (çünki avtomatik göndərilmir), amma localStorage-da saxlandıqda XSS hücumlarına qarşı həssasdır (oğurlanmış token istifadə edilə bilər).
- Web Storage API (localStorage və sessionStorage):
- Brauzerdə key-value şəklində məlumat saxlamaq üçün nəzərdə tutulub (cookie-lərdən daha çox yer təklif edir, adətən 5-10MB).
localStorage
məlumatı brauzer bağlanıb açılanda belə saxlayır.sessionStorage
məlumatı yalnız cari brauzer tab-ı/pəncərəsi açıq olduğu müddətcə saxlayır.- Müqayisə: Cookie-lərdən fərqli olaraq, Web Storage-dakı məlumatlar serverə avtomatik göndərilmir. Lazım gələrsə, JavaScript ilə oxunub istəklərə (məsələn, header və ya body-də) əlavə edilməlidir. Həmçinin, XSS hücumlarına qarşı həssasdırlar, çünki JS ilə tam əlçatandırlar. Həssas session məlumatlarını burada saxlamaq adətən tövsiyə edilmir. UI state-i, istifadəçi preferences, offline data üçün daha uyğundur.