Session یکی از مهمترین بخشهای سیستم احراز هویت در برنامههای PHP است. زمانی که کاربر وارد حساب خود میشود، برنامه معمولاً یک Session برای او ایجاد میکند تا در درخواستهای بعدی بتواند تشخیص دهد این درخواست متعلق به همان کاربر است.
اما اگر Session به شکل نادرست مدیریت شود، مهاجم ممکن است بتواند Session کاربر را سرقت کند یا Session ID مشخصی را از قبل به کاربر تحمیل کند.
دو مورد مهم در این زمینه عبارتاند از:
- Session Hijacking
- Session Fixation
شناخت این دو آسیبپذیری برای هر توسعهدهنده PHP که با سیستم Login، پنل کاربری یا APIهای مبتنی بر Session کار میکند، اهمیت زیادی دارد.
در این مقاله ابتدا مفهوم Session را مرور میکنیم و سپس با مثالهای عملی یاد میگیریم چگونه Session را در PHP امنتر مدیریت کنیم.
# Session چیست؟
Session مکانیزمی برای نگهداری اطلاعات مربوط به یک کاربر در سمت سرور است.
مثلاً بعد از ورود موفق کاربر:
$_SESSION['user_id'] = 25;
در درخواستهای بعدی برنامه میتواند بفهمد کاربر مربوط به کدام حساب است.
در PHP معمولاً Session با:
session_start();
شروع میشود.
مثلاً:
<?php
session_start();
$_SESSION['user_id'] = 25;
بعداً میتوانیم مقدار را بخوانیم:
<?php
session_start();
echo $_SESSION['user_id'];
برای آشنایی کاملتر با مفهوم Session میتوانید مقاله «Session در PHP چیست؟» را در کلاستر PHP مطالعه کنید.
# Session ID چیست؟
Session ID یک شناسه منحصربهفرد است که PHP برای شناسایی Session کاربر استفاده میکند.
مثلاً ممکن است مرورگر یک Cookie شبیه این داشته باشد:
PHPSESSID=abc123...
مرورگر این Cookie را در درخواستهای بعدی ارسال میکند.
سرور نیز بر اساس Session ID، Session مربوط به کاربر را پیدا میکند.
به شکل ساده:
Browser
│
│ PHPSESSID
▼
Server
│
▼
User Session
│
▼
user_id = 25
بنابراین Session ID عملاً نقش یک شناسه دسترسی به Session را دارد.
اگر مهاجم بتواند Session ID معتبر یک کاربر را به دست آورد، در شرایطی ممکن است بتواند خودش را به جای آن کاربر معرفی کند.
# Session Hijacking چیست؟
Session Hijacking یا سرقت Session به حالتی گفته میشود که مهاجم Session معتبر یک کاربر را به دست میآورد و از آن برای دسترسی به حساب کاربر استفاده میکند.
فرض کنید کاربر وارد حساب خود شده است:
User
↓
Login
↓
Session Created
↓
PHPSESSID
اگر مهاجم Session ID معتبر را به دست آورد:
Attacker
↓
Stolen Session ID
↓
Server
↓
Existing User Session
ممکن است سرور تصور کند درخواست مهاجم متعلق به همان کاربر اصلی است.
این یکی از دلایلی است که محافظت از Session ID اهمیت زیادی دارد.
# Session Hijacking چگونه ممکن است اتفاق بیفتد؟
راههای مختلفی میتوانند باعث افشای Session ID شوند.
برای مثال:
- انتقال اطلاعات Session روی اتصال ناامن
- XSS
- بدتنظیم بودن Cookie
- دستگاه آلوده
- افشای اطلاعات حساس
- لاگ کردن اشتباه Session ID
- اشتراکگذاری Session ID
- تنظیمات نادرست سرور
البته این موارد شرایط و سناریوهای متفاوتی دارند و وجود یک مورد به تنهایی لزوماً به معنای وجود آسیبپذیری قابل سوءاستفاده نیست.
# نقش HTTPS در امنیت Session
یکی از مهمترین اقدامات، استفاده از HTTPS است.
بد:
HTTP
بهتر:
HTTPS
HTTPS باعث میشود ارتباط بین مرورگر و سرور رمزنگاری شود.
برای مثال:
Browser
│
│ Encrypted HTTPS
▼
Web Server
در نتیجه شنود ساده ترافیک شبکه برای استخراج Session Cookie بسیار دشوارتر میشود.
اما باید توجه کنیم:
> HTTPS به تنهایی تمام مشکلات Session را حل نمیکند.
هنوز باید Cookieها، Session ID، XSS، Session Fixation و سایر بخشهای سیستم به شکل صحیح مدیریت شوند.
# Cookie مربوط به Session را امن کنیم
یکی از مهمترین قسمتهای امنیت Session، تنظیم صحیح Cookie است.
سه ویژگی مهم عبارتاند از:
Secure
HttpOnly
SameSite
# ویژگی Secure
وقتی Cookie دارای:
Secure
باشد، مرورگر آن را فقط روی اتصال HTTPS ارسال میکند.
در PHP میتوانیم تنظیمات Cookie Session را مشخص کنیم.
مثلاً:
session_set_cookie_params([
'secure' => true,
]);
این تنظیم در محیط Production که HTTPS فعال است اهمیت زیادی دارد.
# ویژگی HttpOnly
با فعال کردن:
HttpOnly
جاوااسکریپت سمت مرورگر نمیتواند به Cookie دسترسی مستقیم داشته باشد.
مثلاً:
session_set_cookie_params([
'httponly' => true,
]);
این ویژگی میتواند ریسک سرقت Cookie از طریق بعضی سناریوهای XSS را کاهش دهد.
اما یک نکته مهم:
> HttpOnly باعث جلوگیری از خود XSS نمیشود.
اگر برنامه شما XSS داشته باشد، مهاجم همچنان ممکن است بتواند اقدامات دیگری را در زمینه کاربر انجام دهد.
بنابراین باید XSS نیز به شکل مستقل مدیریت شود.
# ویژگی SameSite
ویژگی:
SameSite
نحوه ارسال Cookie در درخواستهای Cross-Site را کنترل میکند.
مثلاً:
session_set_cookie_params([
'samesite' => 'Lax',
]);
مقادیر رایج:
Strict
Lax
None
هستند.
برای بسیاری از برنامههای معمول، Lax میتواند انتخاب مناسبی باشد، اما مقدار مناسب به معماری برنامه و نیازهای Cross-Site آن بستگی دارد.
# تنظیم مناسب Cookie Session
میتوانیم تنظیمات Session Cookie را قبل از:
session_start();
مشخص کنیم:
<?php
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
نکته مهم:
session_set_cookie_params() باید قبل از شروع Session اجرا شود.
# Session Fixation چیست؟
Session Fixation با Session Hijacking متفاوت است.
در Session Hijacking مهاجم تلاش میکند یک Session ID معتبر موجود را به دست آورد.
اما در Session Fixation، مهاجم تلاش میکند Session ID مشخصی را قبل از احراز هویت کاربر به او تحمیل کند.
سناریوی ساده:
Attacker
↓
Session ID مشخص
↓
Victim
↓
Login
↓
Same Session ID
اگر برنامه بعد از Login Session ID را تغییر ندهد، مهاجم ممکن است بتواند همان Session را دنبال کند.
# مثال مفهومی Session Fixation
فرض کنیم برنامه یک Session ایجاد میکند:
SESSION_ID = ABC123
مهاجم somehow این Session ID را در اختیار دارد.
سپس کاربر با همان Session ID وارد حساب میشود.
اگر بعد از Login برنامه همچنان از:
ABC123
استفاده کند، Session مربوط به حساب کاربر به همان شناسه وابسته میماند.
اگر مهاجم بتواند همان Session را استفاده کند، ممکن است بتواند به Session احراز هویتشده دسترسی پیدا کند.
راهکار مهم برای جلوگیری از این مشکل:
session_regenerate_id(true);
است.
# session_regenerate_id() چیست؟
تابع:
session_regenerate_id()
یک Session ID جدید تولید میکند.
مثلاً:
session_regenerate_id(true);
پارامتر true باعث میشود Session ID قبلی نیز حذف شود.
این کار مخصوصاً هنگام تغییر وضعیت امنیتی Session اهمیت دارد.
مثلاً:
Guest
↓
Login
↓
Regenerate Session ID
↓
Authenticated User
# استفاده از session_regenerate_id() بعد از Login
یک نمونه ساده:
<?php
session_start();
if ($loginIsSuccessful) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
}
ترتیب منطقی این است که بعد از موفقیت احراز هویت، Session ID جدید تولید شود و سپس اطلاعات کاربر داخل Session قرار بگیرد.
مثلاً:
if ($loginIsSuccessful) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['authenticated'] = true;
}
# چرا فقط Login مهم نیست؟
ممکن است تصور کنیم Session ID فقط بعد از Login باید تغییر کند.
اما هر زمانی که سطح اعتماد یا وضعیت احراز هویت Session تغییر میکند، باید مدیریت Session ID را در نظر بگیریم.
مثلاً:
Anonymous
↓
Login
↓
Authenticated
یا در بعضی معماریها:
Normal User
↓
Two-Factor Authentication
↓
Fully Authenticated
تغییر Session ID در نقاط مناسب میتواند ریسک Session Fixation را کاهش دهد.
# Logout صحیح در PHP
Logout نیز فقط به این معنی نیست که:
unset($_SESSION['user_id']);
را اجرا کنیم.
بهتر است Session به شکل کاملتر خاتمه داده شود.
مثلاً:
<?php
session_start();
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'] ?? '',
$params['secure'],
$params['httponly']
);
}
session_destroy();
این روش Cookie Session را نیز منقضی میکند.
در پروژههای واقعی میتوان این منطق را در یک سرویس یا تابع مجزا قرار داد.
# Session ID را در URL قرار ندهید
یکی از کارهای نامناسب:
https://example.com/profile?PHPSESSID=abc123
است.
Session ID نباید به شکل معمول در URL قرار بگیرد.
زیرا URL ممکن است در مکانهایی مانند:
- Browser History
- Access Log
- Analytics
- Referrer
- Screenshot
- Bookmark
ثبت شود.
بهتر است Session از طریق Cookie مدیریت شود.
در PHP میتوان تنظیمات Session را طوری انجام داد که Session ID از Cookie استفاده کند.
مثلاً:
ini_set('session.use_only_cookies', '1');
ini_set('session.use_strict_mode', '1');
# session.use_strict_mode چیست؟
PHP قابلیتی به نام:
session.use_strict_mode
دارد.
میتوان آن را فعال کرد:
ini_set('session.use_strict_mode', '1');
این تنظیم باعث میشود PHP در مدیریت Session IDهایی که توسط کلاینت ارائه میشوند، رفتار محدودکنندهتری داشته باشد.
فعال کردن Strict Mode یکی از تنظیمات مفید برای کاهش ریسک Session Fixation است.
# تنظیمات پیشنهادی Session در PHP
برای یک برنامه معمولی میتوان تنظیمات Session را در نظر گرفت:
<?php
ini_set('session.use_only_cookies', '1');
ini_set('session.use_strict_mode', '1');
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
در محیط Production باید مطمئن شوید سایت واقعاً از HTTPS استفاده میکند.
# آیا Session ID باید در دیتابیس ذخیره شود؟
در بسیاری از برنامهها لازم نیست خود Session ID را در دیتابیس ذخیره کنیم.
PHP میتواند Session را در Storage مخصوص خودش نگهداری کند.
در پروژههای بزرگ ممکن است Session Storage به سرویسهایی مانند Redis منتقل شود.
مثلاً:
PHP
↓
Redis
↓
Session Data
اما استفاده از Redis یا Database به تنهایی مشکل امنیت Session را حل نمیکند.
تنظیمات Cookie و مدیریت صحیح Session همچنان اهمیت دارند.
# Session و XSS چه ارتباطی دارند؟
اگر برنامه شما XSS داشته باشد، مهاجم ممکن است بتواند اقدامات مختلفی را در Context کاربر انجام دهد.
مثلاً اگر Cookie مربوط به Session:
HttpOnly
نباشد، در بعضی سناریوها JavaScript میتواند به Cookie دسترسی داشته باشد.
برای مثال، چنین کدی خطرناک است:
document.cookie
اما اگر Cookie با:
HttpOnly
تنظیم شده باشد، JavaScript معمولی مرورگر نمیتواند آن Cookie را مستقیماً بخواند.
با این حال:
> HttpOnly جایگزین محافظت در برابر XSS نیست.
برای کاهش ریسک باید خروجی HTML، ورودیها و Contextهای JavaScript نیز به شکل مناسب مدیریت شوند.
# Session و CSRF چه ارتباطی دارند؟
CSRF و Session Hijacking دو مسئله متفاوت هستند.
در CSRF، مهاجم تلاش میکند مرورگر کاربر یک درخواست ناخواسته ارسال کند.
در Session Hijacking، مهاجم تلاش میکند Session معتبر کاربر را در اختیار بگیرد یا از آن استفاده کند.
مثلاً:
CSRF
User Browser
↓
Unwanted Request
↓
Server
اما:
Session Hijacking
Stolen Session
↓
Attacker
↓
Server
Session Cookie امن، HTTPS و CSRF Token هر کدام نقش متفاوتی دارند.
برای محافظت کامل باید هر تهدید را با مکانیزم مناسب خودش مدیریت کنیم.
# آیا session_regenerate_id(true) جلوی Session Hijacking را میگیرد؟
خیر.
این نکته بسیار مهم است.
تابع:
session_regenerate_id(true);
بیشتر برای کاهش ریسک Session Fixation و چرخش Session ID استفاده میشود.
اگر مهاجم قبلاً Session ID فعلی کاربر را سرقت کرده باشد، صرفاً اضافه کردن این تابع به کد، تمام سناریوهای Hijacking را حل نمیکند.
برای کاهش ریسک باید مجموعهای از اقدامات را انجام دهیم:
HTTPS
+
Secure Cookie
+
HttpOnly
+
SameSite
+
Session Regeneration
+
Strict Mode
+
XSS Protection
+
CSRF Protection
+
Logout
+
Session Expiration
# Session Timeout
یکی دیگر از اقدامات مفید، محدود کردن طول عمر Session است.
فرض کنید کاربر برای مدت بسیار طولانی وارد حساب باقی بماند.
در صورت افشای Session، پنجره زمانی سوءاستفاده نیز میتواند طولانی شود.
میتوان در سطح برنامه زمان آخرین فعالیت را ثبت کرد:
$_SESSION['last_activity'] = time();
سپس بررسی کرد:
$timeout = 1800;
if (
isset($_SESSION['last_activity']) &&
time() - $_SESSION['last_activity'] > $timeout
) {
$_SESSION = [];
session_destroy();
exit('Session شما منقضی شده است.');
}
$_SESSION['last_activity'] = time();
در این مثال Timeout برابر 30 دقیقه است.
مقدار مناسب به نوع برنامه بستگی دارد.
# Absolute Session Timeout
علاوه بر Idle Timeout میتوان یک زمان حداکثری نیز تعیین کرد.
مثلاً:
Idle Timeout
30 minutes
Absolute Timeout
8 hours
یعنی حتی اگر کاربر دائماً فعال باشد، Session بعد از مدت مشخصی نیازمند تمدید یا Login مجدد شود.
این موضوع برای سیستمهای حساس میتواند مفید باشد.
# Session Regeneration دورهای
در بعضی معماریها میتوان Session ID را در بازههای زمانی مشخص نیز تغییر داد.
برای مثال:
if (
!isset($_SESSION['last_regeneration']) ||
time() - $_SESSION['last_regeneration'] > 900
) {
session_regenerate_id(true);
$_SESSION['last_regeneration'] = time();
}
در این مثال تقریباً هر 15 دقیقه Session ID تغییر میکند.
اما در پروژههای واقعی باید این موضوع با معماری Session و نحوه مدیریت درخواستهای همزمان به دقت بررسی شود.
# مدیریت Session در Login
یک ساختار مناسب Login میتواند شبیه این باشد:
<?php
session_start();
if ($loginIsSuccessful) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['authenticated'] = true;
$_SESSION['login_time'] = time();
$_SESSION['last_activity'] = time();
}
به این ترتیب بعد از احراز هویت:
- Session ID تغییر میکند.
- شناسه کاربر ذخیره میشود.
- وضعیت احراز هویت ثبت میشود.
- زمان Login ثبت میشود.
- زمان آخرین فعالیت ثبت میشود.
# Session ID را Log نکنید
یکی از اشتباهات خطرناک این است که Session ID را در Log ذخیره کنیم.
مثلاً:
error_log(session_id());
این کار در Production میتواند مشکل امنیتی ایجاد کند.
اگر Logها افشا شوند، اطلاعات Session نیز ممکن است در معرض خطر قرار بگیرد.
بنابراین بهتر است Session ID را:
- در Log ذخیره نکنیم.
- در Error Message نمایش ندهیم.
- در URL قرار ندهیم.
- برای Debug به کاربر نشان ندهیم.
# Session ID را داخل HTML نمایش ندهید
نباید Session ID را در HTML قرار دهیم:
<div>
PHPSESSID=abc123
</div>
یا آن را در JavaScript قرار دهیم:
const sessionId = "abc123";
Session ID باید تا حد امکان در لایه Cookie و مدیریت داخلی Session باقی بماند.
# Session و دستگاههای مختلف
در سیستمهای حساس ممکن است بخواهیم Sessionهای فعال کاربر را مدیریت کنیم.
مثلاً:
User
├── Chrome / Windows
├── Firefox / Linux
└── Mobile
میتوان برای هر Login یک رکورد Session ایجاد کرد و به کاربر اجازه داد:
Sessionهای فعال
----------------
Windows - Chrome
Android - Chrome
Linux - Firefox
[خروج از این دستگاه]
[خروج از همه دستگاهها]
این معماری در سیستمهایی که امنیت حساب اهمیت بیشتری دارد، کاربردی است.
# خروج از همه دستگاهها
اگر Sessionهای کاربر را در Storage مخصوص خودمان مدیریت کنیم، میتوانیم قابلیتی مانند:
Logout All Devices
ایجاد کنیم.
مثلاً یک نسخه Session یا Token برای کاربر نگهداری شود:
user_session_version = 5
و هنگام تغییر آن:
5 → 6
Sessionهای قبلی دیگر معتبر نباشند.
این روش به معماری برنامه بستگی دارد و میتواند برای مدیریت Sessionهای متعدد مفید باشد.
# آیا تغییر IP کاربر راهکار خوبی است؟
گاهی پیشنهاد میشود Session را به IP کاربر قفل کنیم.
مثلاً:
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
و بعد IP را بررسی کنیم.
اما این روش همیشه مناسب نیست.
زیرا IP کاربر ممکن است به دلایل مختلف تغییر کند؛ مثلاً:
- شبکه موبایل
- VPN
- Proxy
- تغییر شبکه
- برخی معماریهای NAT
بنابراین نباید صرفاً بر اساس IP تصمیم بگیریم که Session معتبر یا نامعتبر است.
در سیستمهای حساس میتوان از روشهای تکمیلی استفاده کرد، اما باید اثر آن روی کاربران واقعی نیز در نظر گرفته شود.
# User-Agent Binding چطور؟
مشابه IP میتوان User-Agent را ذخیره کرد.
مثلاً:
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
اما User-Agent نیز یک معیار امنیتی قطعی نیست.
بنابراین نباید آن را تنها مکانیزم تشخیص سرقت Session قرار داد.
# استفاده از HTTPS اجباری در Production
برای سیستمهای Login و Session، HTTPS باید یک جزء اصلی معماری باشد.
در سمت Web Server بهتر است HTTP به HTTPS Redirect شود.
همچنین Cookie مربوط به Session باید:
Secure
باشد.
در نتیجه:
HTTP
↓
Redirect
↓
HTTPS
↓
Secure Session Cookie
قرار میگیرد.
# یک تنظیم کاملتر برای Session
میتوان یک فایل مانند:
bootstrap.php
ایجاد کرد:
<?php
ini_set('session.use_only_cookies', '1');
ini_set('session.use_strict_mode', '1');
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
سپس در صفحات نیازمند Session:
require_once __DIR__ . '/bootstrap.php';
استفاده کنیم.
این کار باعث میشود تنظیمات امنیتی Session در نقاط مختلف پروژه تکرار نشوند.
# نمونه Login امنتر
یک ساختار ساده:
<?php
require_once __DIR__ . '/bootstrap.php';
// بررسی username و password
if ($loginIsSuccessful) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['authenticated'] = true;
$_SESSION['login_time'] = time();
$_SESSION['last_activity'] = time();
header('Location: /dashboard.php');
exit;
}
نکته مهم این است که قبل از این بخش، احراز هویت باید به شکل امن انجام شده باشد.
برای Password نیز باید از توابعی مانند:
password_hash()
و:
password_verify()
استفاده شود.
# Session Fixation و Login
یکی از مهمترین قوانین عملی:
قبل از Login
↓
Session
↓
Login موفق
↓
session_regenerate_id(true)
↓
Authenticated Session
به این ترتیب Session مربوط به قبل از Login با Session بعد از Login یکسان باقی نمیماند.
# Session Hijacking و XSS
اگر مهاجم بتواند JavaScript مخرب را در صفحه اجرا کند، ممکن است بتواند از Context کاربر سوءاستفاده کند.
به همین دلیل باید در کنار تنظیمات Session، مقاله XSS را نیز جدی بگیرید.
راهکارهای مهم:
Output Escaping
+
Content Security Policy
+
HttpOnly Cookie
+
Input Handling
هیچکدام به تنهایی کافی نیستند.
# Session Hijacking و CSRF
CSRF و Hijacking را نباید با یکدیگر اشتباه گرفت.
برای CSRF:
CSRF Token
+
SameSite
+
Origin/Referer Validation
میتواند به عنوان بخشی از دفاع استفاده شود.
برای Session Hijacking:
HTTPS
+
Secure
+
HttpOnly
+
Session Regeneration
+
Strict Mode
اهمیت بیشتری دارد.
در سیستم امن، این دفاعها میتوانند در کنار هم استفاده شوند.
# چکلیست امنیت Session در PHP
قبل از انتشار سیستم Login، موارد زیر را بررسی کنید:
- [ ] سایت Production از HTTPS استفاده میکند.
- [ ] Cookie Session دارای
Secureاست. - [ ] Cookie Session دارای
HttpOnlyاست. - [ ]
SameSiteمتناسب با معماری تنظیم شده است. - [ ]
session.use_only_cookiesفعال است. - [ ]
session.use_strict_modeفعال است. - [ ] بعد از Login، Session ID تغییر میکند.
- [ ] هنگام تغییر سطح دسترسی Session نیز Regeneration در نظر گرفته شده است.
- [ ] Session ID در URL قرار نمیگیرد.
- [ ] Session ID در Logها ذخیره نمیشود.
- [ ] Session ID در HTML یا JavaScript قرار نمیگیرد.
- [ ] Session Timeout مناسب وجود دارد.
- [ ] Logout به شکل کامل انجام میشود.
- [ ] Sessionهای حساس امکان ابطال دارند.
- [ ] XSS در برنامه کنترل شده است.
- [ ] CSRF برای درخواستهای لازم محافظت شده است.
- [ ] IP یا User-Agent به عنوان تنها معیار امنیت Session استفاده نمیشود.
- [ ] فایلهای حساس Session Storage از دسترسی عمومی خارج هستند.
# تفاوت Session Hijacking و Session Fixation
برای جمعبندی تفاوت این دو آسیبپذیری:
| موضوع | Session Hijacking | Session Fixation |
|---|---|---|
| مفهوم | سرقت Session معتبر | تحمیل Session ID به کاربر |
| هدف | استفاده از Session موجود | کنترل Session قبل/بعد از Login |
| زمان مهم | بعد از ایجاد Session | معمولاً قبل از احراز هویت |
| دفاع مهم | HTTPS و Cookie امن | session_regenerate_id() |
| Strict Mode | مفید | بسیار مهم |
| HttpOnly | کاهش برخی ریسکها | مکمل |
| Secure | کاهش ریسک افشای Cookie | مکمل |
| Logout | ابطال Session | مکمل |
# یک معماری مناسب برای Session امن
میتوانیم کل فرآیند را به شکل زیر تصور کنیم:
User
│
▼
HTTPS
│
▼
Secure Session Cookie
│
▼
Strict Session Mode
│
▼
Login
│
▼
session_regenerate_id(true)
│
▼
Authenticated Session
│
┌───────┴────────┐
▼ ▼
Timeout Authorization
│ │
└───────┬────────┘
▼
Logout
│
▼
Session Destroyed
این معماری باعث میشود امنیت Session به یک کنترل واحد وابسته نباشد.
# جمعبندی
Session بخش بسیار مهمی از سیستم احراز هویت در PHP است و باید مانند یک داده حساس با آن رفتار شود.
دو تهدید مهم عبارتاند از:
Session Hijacking
Session Fixation
در Session Hijacking، مهاجم تلاش میکند Session معتبر کاربر را به دست آورد.
در Session Fixation، مهاجم تلاش میکند Session مشخصی را قبل از احراز هویت به کاربر تحمیل کند.
برای کاهش این ریسکها میتوان از مجموعهای از اقدامات استفاده کرد:
HTTPS
Secure Cookie
HttpOnly Cookie
SameSite
Strict Session Mode
Session ID Regeneration
Session Timeout
Secure Logout
XSS Protection
CSRF Protection
یکی از مهمترین نکات عملی این مقاله این است که بعد از Login موفق، Session ID را تغییر دهیم:
session_regenerate_id(true);
اما امنیت Session فقط با همین یک تابع ایجاد نمیشود. امنیت مناسب نتیجه ترکیب چندین لایه دفاعی در کل برنامه است.
اگر سیستم PHP شما دارای Login، پنل مدیریت، حساب کاربری، خرید، پرداخت یا اطلاعات حساس است، مدیریت صحیح Session باید از همان مرحله طراحی معماری در نظر گرفته شود.





