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 चेतावनी देता है किPathsecurity 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/ langSecurity attributes: Secure, HttpOnly और SameSite
ये attributes सीमित करते हैं कि cookie कैसे leak या misuse हो सकती है। हर attribute एक रास्ता बंद करता है, इसलिए जानें कि वह क्या बंद नहीं करता।
Secure: cookie सिर्फ़ HTTPS पर भेजी जाती है, इसलिए plain HTTP traffic से पढ़ी नहीं जा सकती।HttpOnly: cookiedocument.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 याfetchcalls पर नहीं।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, explicitSameSite=LaxयाStrict, कोईDomainनहीं जब तक subdomains को ज़रूरत न हो, और कोईExpiresयाMax-Ageनहीं, क्योंकि OWASP Session Management Cheat Sheet non-persistent session cookies की सलाह देती है।
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 और
Refererheaders में leak होता है।
Set-Cookie में सिर्फ़ उसका random id भेजता है; logout को वह record ख़त्म करना चाहिए, इसलिए जब tester पुराना id replay करता है, तो उसे login page पर redirect किया जाता है।- ब्राउज़र test account
- वेब सर्वर
portal.example - सेशन स्टोर memory, database या cache
- 1 ब्राउज़र से वेब सर्वर तक: Login करना
POST /login - 2 वेब सर्वर से सेशन स्टोर तक: नए random id के साथ session बनाना login से पहले वाला id काम करना बंद करता है
- 3 वेब सर्वर से ब्राउज़र तक: Browser को सिर्फ़ id जाता है जवाब
Set-Cookie: sid=k3Vq…; Secure; HttpOnly - 4 ब्राउज़र से वेब सर्वर तक: हर matching request में यह जाता है
Cookie: sid=k3Vq… - 5 वेब सर्वर से सेशन स्टोर तक: id lookup: live session idle timer फिर से शुरू
- 6 वेब सर्वर से ब्राउज़र तक: इस user का dashboard जवाब
200 OK - 7 ब्राउज़र से वेब सर्वर तक: Logout करना
POST /logout - 8 वेब सर्वर से सेशन स्टोर तक: Session record ख़त्म करना असल में logout करने वाला step
- 9 वेब सर्वर से ब्राउज़र तक: Cookie delete करना जवाब
Set-Cookie: sid=; Path=/; Max-Age=0 - 10 ब्राउज़र से वेब सर्वर तक: Tester पुराना id replay करता है
Cookie: sid=k3Vq… - 11 वेब सर्वर से सेशन स्टोर तक: id lookup: कोई session नहीं
- 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 करने पर (-iresponse headers print करता है,-Hrequest 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आम गलतियाँ
- Cookie browser से गायब हो गई, इसलिए logout को pass कर देना, बिना पुराना identifier server पर replay किए।
- Request के
Cookieheader मेंSecureयाHttpOnlyढूँढना; attributes सिर्फ़Set-Cookieमें दिखते हैं। - Server जो timeout लागू करता है उसे टेस्ट करने की बजाय cookie के
Max-Ageको session timeout मान लेना। - यह मान लेना कि
HttpOnlycross-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- Login वाले
Set-Cookieको attribute दर attribute पढ़ें, या उसे Cookie Analyzer में paste करें। - उससे logout वाले
Set-Cookieकी तुलना करें: name,DomainऔरPath। - तय करें कि 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 Mechanismकुकी कैसे सेट और भेजी जाती हैं: Set-Cookie के एट्रिब्यूट (Expires, Max-Age, Domain, Path, Secure, HttpOnly) और उनके स्कोप नियम।
- OWASP Cheat Sheet Series: Session Managementसेशन आइडेंटिफ़ायर की एंट्रॉपी, कुकी एट्रिब्यूट, एक्सपायरी, लॉगिन के बाद नवीनीकरण और लॉगआउट हैंडलिंग।
- Using HTTP cookies — MDNकुकी की अवधि, स्कोप, Secure/HttpOnly/SameSite एट्रिब्यूट और उनके सुरक्षा निहितार्थ।
- OWASP Cheat Sheet Series: Cross-Site Request Forgery PreventionCSRF से बचाव: सिंक्रोनाइज़र टोकन, SameSite कुकी और ऑरिजिन जाँच।
Mutqan tools से अभ्यास करें
Set-Cookie हेडर पार्स करें और Secure, HttpOnly, SameSite, Domain, Path, एक्सपायरी तथा साइज़ की सर्वोत्तम प्रथाएँ जाँचें।
कच्चे HTTP रिक्वेस्ट/रिस्पॉन्स हेडर को व्याख्या सहित एक संरचित तालिका में बदलें।
मेथड, URL, हेडर, बॉडी और auth विकल्पों से cURL कमांड बनाएँ।
किसी URL को protocol, host, port, path, क्वेरी पैरामीटर, fragment और क्रेडेंशियल में तोड़ें।
और गहराई से
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।