سی ام اس نویسسی ام اس نویسیاد بگیر، سیستم خودتو بنویس
مجلهتماس با ما
سی ام اس نویسسی ام اس نویس

CMS نویس مرجعی برای آموزش برنامه نویسی وب و PHP، توسعه افزونه‌های اختصاصی وردپرس، طراحی ورک‌فلو و اتوماسیون با n8n و توسعه CMS های اختصاصی است. هدف ما ارائه آموزش‌های کاربردی و راهکارهای حرفه‌ای برای توسعه‌دهندگان، کسب‌وکارها و علاقه‌مندان به دنیای برنامه‌نویسی است.

پیوندهای سریع
محصولات فیزیکیمحصولات دیجیتالدوره‌های آموزشی
سی ام اس نویس
مجله سی ام اس نویستماس با ماپنل کاربری
سی ام اس نویس — تمامی حقوق برای سی ام اس نویس محفوظ است. © 1406 تماس با ما09307711941
Session Hijacking و Session Fixation در PHP چیست؟ آموزش افزایش امنیت Session

Session Hijacking و Session Fixation در PHP چیست؟ آموزش افزایش امنیت Session

ممدیر کل سیستم ۲۶ شهریور ۱۴۰۵ ۱۹ دقیقه مطالعه ۱ بازدید
Session Hijacking و Session Fixation در PHP چیست؟ آموزش افزایش امنیت Session

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();

}

به این ترتیب بعد از احراز هویت:

  1. Session ID تغییر می‌کند.
  2. شناسه کاربر ذخیره می‌شود.
  3. وضعیت احراز هویت ثبت می‌شود.
  4. زمان Login ثبت می‌شود.
  5. زمان آخرین فعالیت ثبت می‌شود.

# 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 HijackingSession 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 باید از همان مرحله طراحی معماری در نظر گرفته شود.

نظرات (0)

نظرات پس از تأیید مدیر نمایش داده می‌شوند

هنوز نظری ثبت نشده است؛ اولین نفر باشید!

مقالات مرتبط

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

ساخت CMS با Laravel 12؛ آموزش ساخت سیستم مدیریت محتوا از صفر

۲۴ دقیقه
ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

ساخت فروشگاه اینترنتی با Laravel 12؛ آموزش پروژه‌محور از صفر تا طراحی هسته فروشگاه

۲۲ دقیقه
ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

ساخت Marketplace با Laravel؛ آموزش طراحی فروشگاه چندفروشندگی

۲۲ دقیقه
مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

مدیریت Queueهای سنگین در Laravel؛ آموزش پردازش کارهای طولانی

۲۲ دقیقه