Cookie
بیا یک سناریوی ترسناک اما کاملاً واقعی را تصور کنیم: شما وارد حساب بانکی یا پنل ادمین سایتتان میشوید. یک تب جدید باز میکنید، روی یک لینک ناشناس کلیک میکنید و بوم! شخص دیگری بدون داشتن نام کاربری و رمز عبور شما، وارد حسابتان شده است.
چطور چنین چیزی ممکن است؟ هکر پسورد شما را نشکسته؛ او فقط یک فایل متنی چند کیلوبایتی به نام Cookie را دزدیده است.
در دنیای وب، دزدیدن کوکی دقیقاً معادل دزدیدن هویت شماست. اما چرا؟ و چطور میتوانیم جلوی آن را بگیریم؟
حافظه ماهیِ وب و مشکل فراموشی!
برای درک این فاجعه، اول باید رفتار ذاتاً فراموشکارِ اینترنت را بشناسیم. پروتکل HTTP (که وب روی آن سوار است) Stateless یا «بدون وضعیت» است. یعنی سرورها حافظه ماهی دارند! وقتی شما لاگین میکنید و به صفحه بعدی میروید، سرور کاملاً فراموش میکند که شما چه کسی هستید و دوباره میپرسد: «شما؟»
اینجا بود که دولوپرها مجبور شدند یک راهحل پیدا کنند: ترکیب Session و Cookie.
کلاب شبانه، لیست مهمانها و دستبند VIP
برای درک بهتر، مرورگر خود را یک مهمان و سرور را نگهبانِ یک کلاب شبانه (VIP) در نظر بگیرید:
۱. شما نام کاربری و رمز عبور را میدهید (کارت شناسایی را به نگهبان نشان میدهید). ۲. نگهبان نام شما را در لیست مهمانهای داخل کلاب مینویسد. (این یعنی Session - که در سرور ذخیره میشود). ۳. نگهبان به دور دست شما یک دستبند کاغذی میبندد. (این یعنی Cookie - که در مرورگر شما ذخیره میشود).
از این به بعد، هر بار که میخواهید وارد اتاقهای مختلف کلاب شوید، نگهبان دیگر از شما کارت شناسایی نمیخواهد؛ فقط به دستبند (Cookie) نگاه میکند. اگر دستبند را داشته باشید، درها باز میشوند.
⚠️ مراقب باش: حالا فهمیدید مشکل کجاست؟ نگهبان به «شخص» شما کاری ندارد، او فقط «دستبند» را میشناسد. اگر یک سارق دستبند شما را باز کند و دست خودش ببندد، نگهبان با احترام او را به جای شما وارد کلاب میکند! به این کار Session Hijacking یا سرقت نشست میگویند.
هکرها چطور دستبند ما را میدزدند؟
هکرها راههای مختلفی برای سرقت Cookie دارند، اما رایجترین آنها حملات XSS است. اگر سایت شما در برابر تزریق کدهای مخرب ایمن نباشد، هکر میتواند یک کد جاوااسکریپت ساده مثل console.log(document.cookie) را در سایت اجرا کند.
همین یک خط کد کافیست تا مرورگر تمام کوکیهای کاربر را دو دستی تقدیم هکر کند.
زرههای محافظ: چطور Cookieها را ضدگلوله کنیم؟
برای جلوگیری از این فاجعه، مرورگرها قابلیتهایی به نام Cookie Attributes یا فلگها را معرفی کردند. این فلگها به مرورگر میگویند که چطور باید از این دستبند محافظت کند.
بیایید ۳ نگهبان اصلی کوکیها را بشناسیم:
۱. فلگ HttpOnly (بستن دستهای جاوااسکریپت)
وقتی شما موقع ساخت کوکی فلگ HttpOnly را فعال میکنید، به مرورگر یک دستور قاطع میدهید: «تحت هیچ شرایطی اجازه نده کدهای جاوااسکریپت به این کوکی دسترسی داشته باشند.»
نتیجه؟ حتی اگر هکر موفق شود کد مخرب خود (XSS) را در سایت شما اجرا کند و بنویسد document.cookie، مرورگر یک خروجی خالی به او نشان میدهد. کوکی فقط و فقط در درخواستهای HTTP به سمت سرور ارسال میشود و در مرورگر کاملاً مخفی است.
۲. فلگ Secure (تونل امن)
فرض کنید کاربر شما در یک کافه نشسته و به وایفای عمومی وصل شده است. هکری که در همان کافه است میتواند ترافیک شبکه را شنود کند (حمله Man-in-the-Middle). اگر کوکی شما روی بستر ناامنِ HTTP ارسال شود، هکر راحت آن را روی هوا میقاپد.
با فعال کردن فلگ Secure، به مرورگر میگویید: «این کوکی را فقط و فقط اگر اتصال رمزنگاری شده (HTTPS) بود به سمت سرور بفرست.»
۳. فلگ SameSite (جلوگیری از کلاهبرداری همسایهها)
این فلگ برای مقابله با حملات CSRF طراحی شده است. فرض کنید در تب اولِ مرورگر وارد حساب بانکیتان شدهاید و کوکی آن فعال است. در تب دوم وارد یک سایت مخرب میشوید. سایت مخرب در پسزمینه یک درخواست به آدرس [bank.com/transfer](https://bank.com/transfer) میفرستد. از آنجا که کوکیِ بانک در مرورگر شما فعال است، این درخواستِ مخرب با هویت شما انجام میشود!
فلگ SameSite جلوی این کار را میگیرد و میگوید: «آیا درخواستی که دارد به سمت سرور میآید، از همان دامنه اصلی (Same Site) است یا از یک سایت غریبه؟»
این فلگ سه حالت دارد:
- Strict:
کوکی به هیچوجه برای سایتهای دیگر ارسال نمیشود (بالاترین امنیت).
- Lax:
پیشفرض اکثر مرورگرهاست. کوکی در درخواستهای مستقیم (مثل کلیک روی لینک) ارسال میشود اما در درخواستهای پسزمینه (مثل fetch توسط سایت دیگر) ارسال نمیشود.
- None:
کوکی همهجا ارسال میشود (حتماً باید در کنار فلگ Secure استفاده شود).
💻 پشت صحنه: یک تنظیم کوکیِ استاندارد
اگر یک بکاند دولوپر هستید (مثلاً در Node.js/Express)، کدی که برای ست کردن کوکیِ لاگین مینویسید هرگز نباید ساده باشد. باید شبیه این باشد:
res.cookie('sessionId', 'super_secret_token_123', {
maxAge: 3600000, // انقضا بعد از یک ساعت
httpOnly: true, // جاوااسکریپت دسترسی نداشته باشد
secure: true, // فقط روی HTTPS ارسال شود
sameSite: 'strict' // فقط در همین دامنه معتبر باشد
});
💡 تحلیل کد: ما به مرورگر گفتیم این کوکیِ احراز هویت است. جاوااسکریپت حق دیدن آن را ندارد (httpOnly)، در شبکههای ناامن ارسال نمیشود (secure) و هیچ سایت ثالثی حق استفاده از آن را برای ارسال درخواست ندارد (sameSite).
جمعبندی کاربردی
- مهمترین چیزی که یاد گرفتیم: داشتن کوکی به معنای داشتن هویت کاربر است. اگر از کوکیهای احراز هویت (Auth Cookies) مراقبت نکنید، اکانت کاربران شما در خطر سرقت است.
- چه زمانی از این فلگها استفاده کنیم؟ همیشه! برای هر کوکی که حاوی اطلاعات حساس (مثل توکن لاگین، Session ID و...) است، استفاده از
HttpOnlyوSecureاجباری است. - قدم بعدی شما: همین الان کدهای بکاند یا تنظیمات فریمورک خود را چک کنید. آیا کوکیهای مربوط به لاگین کاربران، با این ۳ فلگ حیاتی محافظت شدهاند یا درِ کلاب را برای هکرها باز گذاشتهاید؟
۲