HTTP कुकीज़ और सेशन

HTTP stateless है: हर request अपने आप में अलग होती है। Cookie वह तरीका है जिससे server browser से एक value याद रखने को कहता है: response में Set-Cookie: sid=k3Vq9XbT2mR7wLp4; Path=/; Secure; HttpOnly आता है, और उसके बाद browser हर matching request में Cookie: sid=k3Vq9XbT2mR7wLp4 जोड़ता है। Session server वाला हिस्सा है: कौन login है, इसका record, जो server पर रहता है और उसी identifier से मिलता है।

जब आप किसी shop में login करके अपनी order history खोलते हैं, तो shop को पता चलता है कि यह आप हैं, सिर्फ़ इसलिए कि browser ने session cookie भेजी और server को उसके लिए live session मिला। Live session के बिना request को login redirect या 401 response मिलता है, जो आपने HTTP status codes में देखे थे।

यह क्यों ज़रूरी है

Login के पीछे का लगभग हर feature इसी mechanism पर टिका है, और इसके कई defects security defects होते हैं: ऐसा session identifier जिसे scripts पढ़ सकें, जो plain HTTP पर जाए, जो logout के बाद भी काम करे या कभी expire न हो, किसी और को user बनकर काम करने देता है। इनमें से कुछ भी happy-path run में नहीं दिखता।

ये checks सस्ते और ठोस हैं: developer tools और एक test account से आप देखते हैं कि attribute है या नहीं और replay की गई request reject होती है या नहीं। Exact Set-Cookie line quote करने वाली report से developer configuration जल्दी ठीक कर सकता है।

Scope और lifetime: Domain, Path, Expires और Max-Age

Server हर Set-Cookie header में एक cookie set करता है: पहले name=value, फिर attributes। RFC 6265 तय करता है कि browser उसे कैसे store करता है और बाद की कौन-सी requests को वह मिलती है। Browser वापस सिर्फ़ name=value pairs एक Cookie header में भेजता है, इसलिए attributes response में जाँचें, request में नहीं।

  • Domain: इसके बिना cookie host-only होती है और सिर्फ़ उसी host पर लौटती है जिसने उसे set किया; Domain=portal.example उसे हर subdomain, जैसे docs.portal.example, पर भी भेजता है।
  • Path: cookie उन URLs पर जाती है जिनका path / की सीमा पर cookie path से शुरू होता है, इसलिए Path=/help, /help/start से match करता है, पर /helpdesk से नहीं। RFC 6265 चेतावनी देता है कि Path security boundary नहीं है।
  • Expires (date) या Max-Age (seconds) cookie को persistent बनाते हैं, और दोनों हों तो Max-Age जीतता है। दोनों के बिना वह session cookie है, जो browser session ख़त्म होने पर हट जाती है। Max-Age=0 उसे delete करता है।
  • Cookie की पहचान name, domain और path, तीनों से मिलकर होती है। Delete या overwrite में तीनों दोहराने होंगे; वरना पुरानी cookie बनी रहती है, और overwrite बस उसी name की एक दूसरी cookie जोड़ देता है।
Responses from https://portal.example
Set-Cookie: sid=k3Vq9XbT2mR7wLp4; Path=/; Secure; HttpOnly; SameSite=Lax
Set-Cookie: lang=ar; Domain=portal.example; Path=/; Max-Age=31536000; Secure
Set-Cookie: tour=done; Path=/help; Expires=Fri, 01 Jan 2027 00:00:00 GMT; Secure

Request to                               Cookies the browser sends
https://portal.example/help/start        sid, lang, tour
https://portal.example/dashboard         sid, lang
https://docs.portal.example/             lang

आज़माएँ: कुकी एनालाइज़र आज़माएँ: URL पार्सर

Security attributes: Secure, HttpOnly और SameSite

ये attributes सीमित करते हैं कि cookie कैसे leak या misuse हो सकती है। हर attribute एक रास्ता बंद करता है, इसलिए जानें कि वह क्या बंद नहीं करता।

  • Secure: cookie सिर्फ़ HTTPS पर भेजी जाती है, इसलिए plain HTTP traffic से पढ़ी नहीं जा सकती।
  • HttpOnly: cookie document.cookie से छिपी रहती है, इसलिए injected script उसे copy नहीं कर सकता, पर browser फिर भी उसे requests के साथ भेजता है, इसलिए ऐसा script page के अंदर user बनकर काम कर सकता है।
  • SameSite दूसरी site से शुरू होने वाली requests को control करता है। Strict: cookie कभी नहीं भेजी जाती, इसलिए दूसरी site के link से आया user logged out दिखता है। Lax: सिर्फ़ top-level navigations पर, यानी जब पूरा tab उस site पर जाता है (जैसे link follow करने पर), और GET जैसे safe method के साथ; cross-site form posts, images, frames या fetch calls पर नहीं। None: cross-site requests पर भी भेजी जाती है, जब तक browser settings third-party cookies block न करें, और सिर्फ़ Secure के साथ स्वीकार होती है।
  • "Site" का मतलब registrable domain है, इसलिए docs.portal.example और portal.example एक ही site हैं। SameSite उन RFC 6265bis drafts से आता है जिन्हें browsers implement करते हैं, RFC 6265 से नहीं, और browsers के defaults अलग हैं, इसलिए उम्मीद रखें कि इसे explicit set किया जाए।
  • Session cookie का baseline: Secure, HttpOnly, explicit SameSite=Lax या Strict, कोई Domain नहीं जब तक subdomains को ज़रूरत न हो, और कोई Expires या Max-Age नहीं, क्योंकि OWASP Session Management Cheat Sheet non-persistent session cookies की सलाह देती है।

आज़माएँ: कुकी एनालाइज़र आज़माएँ: HTTP हेडर पार्सर

Server-side sessions: identifier, expiry और logout

Login पर server session record (user, roles, समय) को memory, database या cache जैसे session store में रखता है और Set-Cookie में सिर्फ़ एक random identifier भेजता है। बाद की हर request पर वह identifier ढूँढता है: live session मिले तो request उसी user के रूप में चलती है; वरना page login page पर redirect होता है और API 401 Unauthorized लौटाता है।

यानी दो घड़ियाँ हैं, browser में cookie की और server पर session की, और सुरक्षा सिर्फ़ server की घड़ी देती है, क्योंकि identifier रखने वाला कोई भी उसे भेजता रह सकता है। OWASP Session Management Cheat Sheet ये माँगती है:

  • Cryptographically secure random generator से बना identifier, कम से कम 64 bits entropy (उसे guess करना कितना मुश्किल है, इसका माप) वाला, और user id या timestamp जैसे किसी मतलब के बिना।
  • Login पर और privilege के हर बदलाव पर नया identifier, और पुराना invalid; वरना login से पहले plant किया गया identifier (session fixation) बाद में भी काम करता है।
  • आख़िरी request से गिना जाने वाला idle timeout और login से गिना जाने वाला absolute timeout, दोनों server पर लागू।
  • ऐसा logout जो server पर record ख़त्म करे; Max-Age=0 से cookie delete करना सिर्फ़ browser को साफ़ करता है।
  • Identifier सिर्फ़ cookie में, URL में कभी नहीं, जहाँ से वह history, logs और Referer headers में leak होता है।
Login session को server पर रखता है और Set-Cookie में सिर्फ़ उसका random id भेजता है; logout को वह record ख़त्म करना चाहिए, इसलिए जब tester पुराना id replay करता है, तो उसे login page पर redirect किया जाता है।
  • ब्राउज़र test account
  • वेब सर्वर portal.example
  • सेशन स्टोर memory, database या cache
  1. 1 ब्राउज़र से वेब सर्वर तक: Login करना POST /login
  2. 2 वेब सर्वर से सेशन स्टोर तक: नए random id के साथ session बनाना login से पहले वाला id काम करना बंद करता है
  3. 3 वेब सर्वर से ब्राउज़र तक: Browser को सिर्फ़ id जाता है जवाब Set-Cookie: sid=k3Vq…; Secure; HttpOnly
  4. 4 ब्राउज़र से वेब सर्वर तक: हर matching request में यह जाता है Cookie: sid=k3Vq…
  5. 5 वेब सर्वर से सेशन स्टोर तक: id lookup: live session idle timer फिर से शुरू
  6. 6 वेब सर्वर से ब्राउज़र तक: इस user का dashboard जवाब 200 OK
  7. 7 ब्राउज़र से वेब सर्वर तक: Logout करना POST /logout
  8. 8 वेब सर्वर से सेशन स्टोर तक: Session record ख़त्म करना असल में logout करने वाला step
  9. 9 वेब सर्वर से ब्राउज़र तक: Cookie delete करना जवाब Set-Cookie: sid=; Path=/; Max-Age=0
  10. 10 ब्राउज़र से वेब सर्वर तक: Tester पुराना id replay करता है Cookie: sid=k3Vq…
  11. 11 वेब सर्वर से सेशन स्टोर तक: id lookup: कोई session नहीं
  12. 12 वेब सर्वर से ब्राउज़र तक: Login page, dashboard data कभी नहीं जवाब 302 Location: /login पास

परिणाम: Cookie सिर्फ़ चाबी है: logout और timeouts user को तभी बचाते हैं जब server record ख़त्म करता है।

Worked example: login session को trace और टेस्ट करना

Test environment में एक staff portal, https://portal.example, की requirement है: "15 मिनट तक कोई activity न हो तो session ख़त्म होता है, और login के 8 घंटे बाद भी। Log out से session ख़त्म होता है।" Test account और खुले Network panel के साथ tester login करता है, dashboard खोलता है, logout करता है और नीचे वाला exchange record करता है।

सिर्फ़ वही systems टेस्ट करें जो आपके हैं या जिन्हें टेस्ट करने की अनुमति है, और reports में session identifiers mask करें, क्योंकि copy किया गया live identifier password की तरह काम करता है। हर check एक test case बनता है:

  • Attributes: sid में Secure, HttpOnly और SameSite=Lax हैं, और कोई Domain या Max-Age नहीं।
  • Renewal: site ने login से पहले ही anonymous visitor को एक session दिया था (Ae5f…); वह value नई value से अलग है, और उसके साथ भेजी गई request login page पर पहुँचती है।
  • Logout: delete वही Path=/ दोहराता है, और curl से पुरानी value replay करने पर (-i response headers print करता है, -H request header जोड़ता है), जैसे curl -i -H "Cookie: sid=k3Vq9XbT2mR7wLp4" https://portal.example/dashboard, /login पर redirect मिलता है, dashboard data कभी नहीं।
  • Boundary पर idle timeout: network delay और server का timer ठीक-ठीक second को भरोसेमंद नहीं रहने देते, इसलिए एक छोटा margin तय करें और boundary के दोनों तरफ़ टेस्ट करें, जैसे 14 मिनट 50 सेकंड idle के बाद की request (अब भी काम करती है) और 15 मिनट 10 सेकंड के बाद वाली (login page)। पूछें कि क्या test environment में छोटे timeouts इस्तेमाल हो सकते हैं।
  • Absolute timeout: लगातार activity के बावजूद session login के 8 घंटे बाद ख़त्म होता है।
  • Scope: docs.portal.example को sid कभी नहीं मिलता।
POST /login HTTP/1.1
Host: portal.example
Cookie: sid=Ae5fUq0Zr8Ty2Nc6

HTTP/1.1 303 See Other
Location: /dashboard
Set-Cookie: sid=k3Vq9XbT2mR7wLp4; Path=/; Secure; HttpOnly; SameSite=Lax

GET /dashboard HTTP/1.1
Host: portal.example
Cookie: sid=k3Vq9XbT2mR7wLp4

POST /logout HTTP/1.1
Host: portal.example
Cookie: sid=k3Vq9XbT2mR7wLp4

HTTP/1.1 303 See Other
Location: /login
Set-Cookie: sid=; Path=/; Max-Age=0; Secure; HttpOnly; SameSite=Lax

आज़माएँ: कुकी एनालाइज़र आज़माएँ: cURL जनरेटर

आम गलतियाँ

  • Cookie browser से गायब हो गई, इसलिए logout को pass कर देना, बिना पुराना identifier server पर replay किए।
  • Request के Cookie header में Secure या HttpOnly ढूँढना; attributes सिर्फ़ Set-Cookie में दिखते हैं।
  • Server जो timeout लागू करता है उसे टेस्ट करने की बजाय cookie के Max-Age को session timeout मान लेना।
  • यह मान लेना कि HttpOnly cross-site scripting (XSS) रोकता है या SameSite हर forged request रोकता है।
  • Domain और Path को नज़रअंदाज़ करना: parent domain पर scoped session cookie, या अलग Path से delete करने वाला logout।
  • Live session identifiers को mask किए बिना bug reports, chats या screenshots में paste करना।

QA का नज़रिया

Session का व्यवहार आम तौर पर framework configuration से आता है, जो अक्सर defaults पर छोड़ दी जाती है, इसलिए session policy जल्दी माँगें: cookie का name और attributes, दोनों timeouts, concurrent sessions, और logout व password change क्या करते हैं। छोटी table के रूप में लिखी जाए तो यह test basis बन जाती है जिसे developers और security reviewers confirm कर सकते हैं; उसमें कोई भी खाली जगह requirement का सवाल है।

इन checks को regression suite में रखें और framework upgrades, proxy या CDN के बदलावों और domain बदलने के बाद दोबारा चलाएँ, क्योंकि ये cookies को चुपचाप बदल देते हैं। Report में masked request और response, browser version और timestamps दें, और session handling पर गहरे attacks security specialists और OWASP Web Security Testing Guide पर छोड़ें।

अभ्यास

Clinic portal की session cookie review करें

आपका काम

Test environment में एक clinic का booking portal नीचे वाले headers भेजता है। एक colleague ने note किया कि logout के बाद भी browser पुरानी SESSION value भेजता है, और curl से उसे replay करने पर 200 OK के साथ user के appointments मिलते हैं। हर defect या risk ढूँढें, बताएँ कि वह कौन-सा rule तोड़ता है, और हर fix के लिए एक confirmation test लिखें।

सामग्री
Response to POST /login on https://clinic.example
Set-Cookie: SESSION=u1042-20261002-0915; Domain=clinic.example; Path=/; Max-Age=2592000

Response to POST /logout
Set-Cookie: SESSION=; Path=/app; Max-Age=0

Login of a second test user at 11:30
Set-Cookie: SESSION=u1043-20261002-1130; Domain=clinic.example; Path=/; Max-Age=2592000
चरण
  1. Login वाले Set-Cookie को attribute दर attribute पढ़ें, या उसे Cookie Analyzer में paste करें।
  2. उससे logout वाले Set-Cookie की तुलना करें: name, Domain और Path।
  3. तय करें कि replay की गई request server पर session के बारे में क्या बताती है।
मॉडल उत्तर दिखाएँ
मॉडल उत्तर

Predictable identifier: यह user number और login की date व time है, जैसा दूसरी value से पक्का होता है, इसलिए दूसरे users के identifiers guess किए जा सकते हैं। यह random होना चाहिए, कम से कम 64 bits entropy के साथ। Test: बार-बार login करने पर values में न user number हो, न time, न कोई दिखने वाला pattern, और code review से पक्का हो कि cryptographically secure generator इस्तेमाल होता है।

Secure, HttpOnly और SameSite नहीं हैं, Domain=clinic.example cookie को हर subdomain पर भेजता है, और Max-Age=2592000 उसे browser restarts के पार 30 दिन रखता है, जो non-persistent session cookies की OWASP सलाह के ख़िलाफ़ है; पूछें कि requirement "remember me" के बारे में क्या कहती है। Test: Cookie Analyzer तीनों attributes दिखाए, और कोई Domain या Max-Age नहीं।

Delete में Path=/app है और Domain नहीं, इसलिए वह original cookie तक नहीं पहुँचता, जिसे browser रखे रहता है, क्योंकि cookie की पहचान name, domain और path, तीनों से मिलकर होती है। उसे वही name, Domain और Path दोहराने होंगे जो login cookie सच में इस्तेमाल करती है (पिछले fix के बाद: कोई Domain नहीं, Path=/)। Test: logout के बाद browser की cookie list में SESSION न हो, और अगली request में कोई SESSION cookie न जाए।

सबसे गंभीर: server ने logout पर session ख़त्म नहीं किया, जबकि logout को server पर record ख़त्म करना चाहिए, इसलिए पुरानी value रखने वाला कोई भी user के appointments देख सकता है। Severity: critical। Test: logout के बाद replay पर login redirect या 401 मिले। Login पर renewal और दोनों timeouts के tests भी जोड़ें।

अक्सर पूछे जाने वाले सवाल

Session cookie और session में क्या फ़र्क है?

Session cookie कोई भी ऐसी cookie है जिसमें Expires या Max-Age नहीं; browser अपना session ख़त्म होने पर उसे हटा देता है, हालाँकि restart पर पिछला session restore करने वाला browser उसे रखे भी रह सकता है। Session server पर वह record है जिसकी ओर identifier इशारा करता है। Identifier session cookie में भी हो सकता है और persistent cookie में भी, और cookie हटाने से server का session ख़त्म नहीं होता, इसीलिए logout और timeouts server की तरफ़ से टेस्ट किए जाते हैं।

30 मिनट का idle timeout हर बार 30 मिनट इंतज़ार किए बिना कैसे टेस्ट करूँ?

Developers से पूछें कि क्या timeout configurable है, और test environment में दो मिनट जैसी छोटी value से mechanism को boundary values के साथ टेस्ट करें। फिर असली value एक बार confirm करें, configuration में या एक लंबे test से, production की तरह configured environment में। Browser में cookie की expiry बदलने से कुछ साबित नहीं होता, क्योंकि फ़ैसला server की घड़ी करती है।

Expired session को 401 मिलना चाहिए या redirect?

यह client पर निर्भर है। Browser page को आम तौर पर login page पर 302 या 303 जैसा redirect मिलता है, और API 401 Unauthorized लौटाता है। जो कभी नहीं होना चाहिए, वह है user के data के साथ 200, या stack trace वाला error page। जाँचें कि तय किया गया व्यवहार हर protected route पर एक जैसा है।

क्या SameSite अकेले cross-site request forgery (CSRF) से बचाता है?

Cross-site request forgery (CSRF) का मतलब है कि कोई दूसरी site logged-in user के browser से आपकी application को एक अनचाही request भिजवा दे, जिसके साथ user की cookies भी चली जाती हैं। SameSite यह risk कम करता है, लेकिन OWASP Cross-Site Request Forgery Prevention Cheat Sheet इसे defence in depth मानती है, anti-CSRF tokens जैसे सही CSRF defence का विकल्प नहीं। Lax दूसरी sites से top-level GET navigations पर cookie अब भी भेजता है, इसलिए GET से पहुँचने वाला हर state बदलने वाला action खुला रहता है। Attribute और token, दोनों टेस्ट करें।

संदर्भ

  • RFC 6265: HTTP State Management MechanismIETF · 2011कुकी कैसे सेट और भेजी जाती हैं: Set-Cookie के एट्रिब्यूट (Expires, Max-Age, Domain, Path, Secure, HttpOnly) और उनके स्कोप नियम।
  • OWASP Cheat Sheet Series: Session ManagementOWASP Foundationसेशन आइडेंटिफ़ायर की एंट्रॉपी, कुकी एट्रिब्यूट, एक्सपायरी, लॉगिन के बाद नवीनीकरण और लॉगआउट हैंडलिंग।
  • Using HTTP cookies — MDNMDN Web Docs (Mozilla)कुकी की अवधि, स्कोप, Secure/HttpOnly/SameSite एट्रिब्यूट और उनके सुरक्षा निहितार्थ।
  • OWASP Cheat Sheet Series: Cross-Site Request Forgery PreventionOWASP FoundationCSRF से बचाव: सिंक्रोनाइज़र टोकन, SameSite कुकी और ऑरिजिन जाँच।

Mutqan tools से अभ्यास करें

Set-Cookie हेडर पार्स करें और Secure, HttpOnly, SameSite, Domain, Path, एक्सपायरी तथा साइज़ की सर्वोत्तम प्रथाएँ जाँचें।

वैलिडेशन

कच्चे HTTP रिक्वेस्ट/रिस्पॉन्स हेडर को व्याख्या सहित एक संरचित तालिका में बदलें।

वेब

मेथड, URL, हेडर, बॉडी और auth विकल्पों से cURL कमांड बनाएँ।

वेब

किसी URL को protocol, host, port, path, क्वेरी पैरामीटर, fragment और क्रेडेंशियल में तोड़ें।

वेब

और गहराई से

इस topic में आपकी प्रगति

QA रोडमैप का हिस्सा