امنیت Session در php

  • آپدیت شده در تاریخ

امنیت Session در php

اپلیکیشن های تحت وب به طور مکرر از سیشن ها برای ساخت یک محیط قابل تعامل با کاربر استفاده می کنند برای همین موضوع امنیت Session در php بسیار مهم است .

همانطور که میداند HTTP یک پروتکل stateless است , به این معنا که سرور نمی تواند تشخیص دهد که این کاربر از قبل این صفحه وب را مشاهده کرده است و یا اینکه کدام کاربر چه درخواستی را ارسال کرده است .

این قابلیت یک مزیت داشت و آن اینکه دیگر نیازی به  ثبت هیچ اطلاعاتی نبود و باعث می شد که انتقال اطلاعات با سرعت بیشتر رد و بدل شود . اما این یکی از ضعف های بزرگ پروتکل http بود که برای مدیریت آن (State Management) باید از روش هایی مثل SESSION و COOKIE ها استفاده می شد .

SESSION چیست ؟

ایده اولیه سیشن ها این بود که سرور یک شناسه id برای ارتباط با کاربر می ساخت , این ID را به مرورگر کاربر ارسال می کرد تا به عنوان شناسه کاربر در یک کوکی ذخیره و در درخواست های بعدی استفاده شود .

روش های بسیار زیادی در وب برای ذخیره سیشن وجود دارد : آرگومان های URL , فیلد های مخفی , دیتابیس , کوکی ها و.. . php از کوکی ها برای ذخیره Session ID ها استفاده می کند . این مقدار کوکی برای هر درخواست فراخوانی می شود . راه دیگر قرار دادن session id در url است . که در اینصورت باید ماژول url rewriting فعال باشد .

پاس دادن مقدار سیشن در آدرس url به هیچ وجه توصیه نمی شود . که در اینصورت با دادن آدرس یک صفحه به یک یوزر دیگر session id کاربر شما به راحتی لو خواهد رفت . استفاده از سیشن در url در جاهایی کاربرد دارد که نشود از کوکی ها استفاده کرد .

قبلا آموزش کار با SESSION در php را آموزش دادیم . پس فقط در این مقاله به امنیت Session در php می پردازیم .

راهکارهای افزایش امنیت Session در php

افزایش امنیت Session در php فقط بخشی از ماجراست . برای افرایش امنیت سیشن باید سه لایه مختلف را امن کنیم .

شبکه > وب سرور > اپلیکیشن تحت وب (PHP)

امنیت سیشن ها در سطح شبکه

همانطور که میدانید پروتکل HTTP تمام درخواست های بین کاربر و سرور را به صورت متن ساده (plain text) رد و بدل می کند . اگر یک هکر به شبکه محلی سرور دسترسی پیدا کند و یا حتی فقط از سرویس های آن شبکه استفاده کند به راحتی می تواند با انجام حملات (Man in the middle) که به مردی در میان معروف است تمام اطلاعات اعم از سیشن و پسورد های وارد شده توسط مدیریت سایت و کاربران و سیشن ها را به راحتی به سرقت ببرد

و خود را به عنوان مدیریت سایت یا یکی از کاربران جا بزند و عملیات مخرب خود را پیاده سازی کند. !

پس سعی کنید از پروتکل HTTP بر روی SSL استفاده کنید که باعث افزودن یک لایه امنیتی به شبکه شما می شود و حتی اگر هکر شبکه شما را اسنیف کند و به سیشن ها و پسورد ها شما دست پیدا کند به هیچ وجه نمی تواند از آن استفاده کنید .

به این دلیل که  HTTPS تمام اطلاعات بینن کاربر و سرور را به صورت encrypt شده تبدیل می کند که شکستن آنها با قدرمندترین سرورها ماه ها یا سال ها طول می کشد.!

امنیت Session در php

امنیت سیشن در php

برای افزایش امنیت SESSION در php راهکارهای مختلفی ارایه دادیم که در قالب مثال و معرفی حملات Session Hijacking یا Session Fixation ادامه خواهیم داد.

حملات Session Fixation و Session Hijacking

همیشه سعی کنید مقدار سیشن کاربر را به صورت رندوم و با الگوریتم های غیرقابل بازگشت استفاده کنید (برای آشنایی با الگوریتم های رمزنگاری در php کلیک کنید )تا از حملات SESSION Fixation در امان باشید .

اگر مثلا سیشن کاربر الف را ۱۰۰ و کاربر ب را ۱۵۰ قرار دهید کاربر به راحتی می تواند با انجام چند تست و پیدا کردن الگوریتم نحوه اختصاص دهی مقدار سیشن به کاربر با حملات bruteforce سیشن کاربران دیگر را پیدا کرده و با ست کردن آنها خود را با دسترسی کاربر دیگر وارد سیستم شود . باگی که در قسمت ورود کارمندان سایت همراه اول بود که بعد از گزارش , رفع شد !.

همچنین سعی کنید به هیچ وجه سیشن را به صورت خام در کوکی ها ذخیره نکنید , همیشه آن را به صورت encode شده (SHA-1 , MD5 ,..) ذخیره کنید .

امنیت Session در php

اعتبارسنجی ورودی های کاربر

برای افزایش امنیت Session در php , اگر مقادیر ست شده در سیشن را از طریق ورودی های کاربر دریافت می کنید , حتما کاراکتر های غیر مجاز را با استفاده از توابع htmlspecialchars یا htmlentities پاکسازی کنید .

برای آموزش کامل تابع htmlentities در php کلیک کنید

فکر کنید اگر قصد داشتید این مقادیر را بدون sanitize کردن در دیتابیس ذخیره کنید , کاربر می توانست با اجرای یک دستور sql حمله sql injection را پیاده سازی و دیتابیس شما را هک کند .!

و یا برای مثال اگر مقادیر را مثل اسم کاربر را در سشن دخیره و در جایی مثل پنل مهمان یا هر جایی دیگر که از آن را برای نمایش اسم کاربر استفاده می کردید در اینصورت یک باگ xss را به صورت خودکار در سایت بوجود آوردید که فرد نفوذگر به راحتی می توانست عملیات مخرب خود را برای ربودن سیشن و کوکی کاربر پیاده سازی کند .

ست کردن سشن بر روی IP

یکی از روش های دیگر برای جلوگیری از حملات SESSION Hijacking یا همان دزدیدن سیشن استفاده از ip و user agent مرورگر کاربر در ساخت سیشن است . که در اینصورت اگر حتی session کاربر لو برود یا اسنیف شود چونکه ip پابلیک آنها باهم یکی نیست ,

به هیچ وجه نمی تواند به اطلاعات کاربری دسترسی پیدا کند . البته user agent  را می شود با انجام چند تست brute force , useragent کاربر را به راحتی پیدا و ست کند ولی این در مورد ip که یک مقدار منحصر به فرد برای هر کاربر در اینترنت است , جواب نمی دهد

به هر حال کد تشخیص هویت کاربر با useragent و ip به اینصورت است

برای ساخت سیشن کاربر ابتدا از طریق آرایه $_SERVER در php مقادیر ip و عامل کاربری (user-agent) را با md5 اینکد و در متغییر سیشن ذخیره می کنیم

در این صفحه بررسی می کنیم اگر مقدار هش ip و useragent کاربر با مقدار md5 دخیره شده یکسان است یا نه , اگر نه کاربر با به صفحه دلخواه ریدایرکت می کنیم.

بازسازی مقدار session ID

یکی از روش های جلوگیری از حملات session hijacking و افزایش امنیت سشن استفاده از تابع از پیش ساخته (in-built) php به نام session_regenerate_id() در انتهای تمام صفحاتی که به احراز هویت با php نیاز می باشد , است .

Session ID حداقل باید در موارد زیر بازسازی شود:

  • زمانی که کاربر وارد میشود (Log in)
  • زمانی که کاربر خارج میشود (Log out)
  • زمانی که کاربر وارد محیط مدیریتی میشود و یا سطح دسترسی کاربر تغییر میکند

اگر بخواهید session id را در هر مثلا ۱۰۰ درخواست یکبار از اول بسازید می توانید به صورت زیر عمل کنید

با اینکار در هر بار بازدید کاربر از صفحات سایت یک سیشن جدید ساخته می شود و اگر فردی سیشن قبلی را داشته باشد سریعا دسترسی آن قظع خواهد شد .!

تعیین تاریخ انقضا برای SESSION در php

یکی از روش های دیگر برای افزایش امنیت Session در php تعیین تاریخ انقضا برای سیشن در php با استفاده از تابع time() است که در مقاله زیر به طور کامل موارد استفاده و پیاده سازی آن را توضیح دادیم .

آموزش تعیین تاریخ انقضا برای SESSION در php

امنیت Session در php

امنیت سیشن در php از طریق وب سرور

به طور پیش فرض هر بار کاربری در سیستم لاگین می کند و یک session id به آن اختصاص می یابد این اطلاعات اعم از id سیشن در فولدر /tmp سیستم عامل لینوکس ذخیره می شود .

فولدر tmp در لینوکس یک دایرکتری با پرمیشن ۷۵۵ برای دسترسی کاربران برای ذخیره فایل های خود در آن به صورتی که دیگر کاربران سیستم بتوانند به آن دسترسی پیدا کنند است . اگر از یک هاست اشتراکی استفاده می کنید افراد دیگری که بر روی این سرور هاست دارند می توانند با رجوع به این فولدر به تمام سیشن ها اگر رمزگذاری نشده باشد , دسترسی پیدا کنید

برای تغییر فولدر ذخیره سازی session ها در هاست باید یک سری از تنظیمات خود php.ini را تغییر بدید . اگر دسترسی ندارید می توانید با توابع خود php آن را تغییر بدهید.

تغییر محل ذخیره سازی سیشن ها در سرور

برای اینکار از تابع ini_set  به صورت زیر استفاده می کنیم.

برای دسترسی به اطلاعات در مورد محل ذخیره سازی سیشن ها و همچنین بررسی آن بعد تغییر , پیدا کردن محل فایل php.ini در سرور و دیدن دیگر تنظیمات و ماژول ها مربوط از تابع phpinfo() استفاده کنید

ست کردن فلگ httponly

اگر فلگ httpOnly برای کوکی ها ست شده باشد , در اینصورت حتی با آسیب پذیر بودن سایت شما به باگ xss , هکر نمی تواند با استفاده از زبان های اسکریپت نویسی سمت کاربر مثل جاواسکریپت به کوکی های ذخیره شده در مرورگر دسترسی پیدا کند .

همچنین دو مورد بالا (محل ذخیره سازی سیشن ها در سرور و ست کردن تاریخ انقضای سیشن) را  از طریق فایل php.ini در سرور اختصاصی و  یا هاست خود به صورت همیشگی ست کنید تا نیازی به تغییر کدهای php نباشد .

راه هایی مثل ذخیره سیشن در دیتابیس mysql است که توصیه می شود حتی برای امنیت استفاده نشود چراکه باعث کند شدن صفحات وب سایت شما می شود و همچنین اگر ورودی های کاربر به درستی فیلتر نشده باشد امکان دارد خطراتی را برای لو رفتن کل اطلاعات دیتابیس شما به حملات sql injection بوجود آورد .

همانطور که دیدید امنیت Session در php یک دید کلی بر روی هر سه لایه شبکه , وب سرور و php را میطلبد و به هیچ عنوان فقط بستگی به کد نویسی شما ندارد و کارهایی تکنیکالی برای ایمن سازی سیشن ها به دلیل نبودن زیرساخت صحیح http که در بالا اشاره کردم , می طلبد .

ولی تمام سعیم را کردم که تمام موارد را پوشش دهم تا شما توسعه دهنده وب , امنیت سیشن و کوکی های خود را در حد بالا افزایش دهید .

زمان زیادی صرف تهیه و نوشتن آموزش امنیت Session در php شده است , پس امیدوارم مفید بوده باشد.

اگر نظر یا سوالی در مورد هر یک از بخش های مورد نظر داشتید از قسمت نظرات اقدام کنید , سریعا پاسخگوی سوالات شما هستیم .

موفق و پیروز باشید

حسن شفیعی علاقه خاصی به برنامه نویسی وب و موبایل دارم و هر روز تلاش می کنم به این حوزه مسلط تر شوم و اطلاعاتم را به شکل کاربردی برای علاقه مندان در وب به اشتراک بگذارم

آموزش های رایگان بیشتر در اینستاگرام ما ...

NETPARADIS /
مطالب زیر را حتما بخوانید
دیدگاه کاربران (۲۲)

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

  1. علی اصغر ولیلو ۱۶ اردیبهشت ۱۳۹۹

    بسیار ممنون از آموزش خوبتون آقای شفیعی
    یک سوال داشتم
    من در صفحه لاگین وقتی که کاربر لاگین میشود یک سیشن با نام کاربری، کاربر می سازم
    و با همون سیشن کاربر با دیتابیس کار میکنه
    آیا این مشکل امنیتی داره ؟
    مثلا اینجا یکی میتونه یکی از سیشن های کاربر دیگر رو به خودش اختصاص بده؟
    و در مورد ip و useragent اگر کاربر از یک wifi استفاده کند اینجا دیگر ip یونیک نیست و کس دیگر هم میتونه اون ip رو داشته باشه الان مشکل امنیتی نخواهیم داشت؟

    پاسخ
    1. حسن شفیعی ۱۶ اردیبهشت ۱۳۹۹

      سلام.خوشحالیم که مفید واقع شده.
      نه مشکلی پیش نمیاد و از همین روش میتونید استفاده کنید

      پاسخ
  2. مصطفی ۲۹ آذر ۱۳۹۸

    سلام . مرسی از مطلبتون . این مطالب به آپدیت شدن احتیاج نداره به نظرتون یه اینکه شما خودتون این کار رو انجام میدید؟
    با تشکر

    پاسخ
    1. حسن شفیعی ۲۹ آذر ۱۳۹۸

      سلام. خوشحالیم که مفید واقع شده.
      تمام راهکارهای ارایه شده قابل استفاده است و برای بعضی موارد که گفته شده باید دسترسی بالاتری روی سرور داشته باشید مثلا از سرورهای مجازی یا اختصاصی استفاده کنید و امکان اعمال تغییرات روی هاست اشتراکی وجود ندارد.
      موفق باشید.

      پاسخ
  3. fatemeh ۷ مهر ۱۳۹۸

    سلام ببخشید من وقتی از این کد ini_set(‘session.cookie_httponly’, true); استفاده میکنم خطا داره برنامه
    میتونم برای کوکی ها از
    setcookie(“expirecookie”, $time , time() + 900, “/”,NULL, NULL, TRUE);
    استفاده کنم ؟ منظورم نوشتن TRUE هست

    پاسخ
    1. حسن شفیعی ۷ مهر ۱۳۹۸

      سلام.
      طبق داکیومنت بله امکانش هست :
      https://www.php.net/manual/en/function.setcookie.php
      موفق باشید.

      پاسخ
  4. sahel ۶ مهر ۱۳۹۸

    سلام وقت بخیر
    ببخشید من یک فولدر به نام test در مسیر ریشه اصلی سایت ایجاد کردم و میخواستم سیشن ها در این فولدر ذخیره کنم . اما نمیشه !!!
    من این کد در صفحه اصلی index ابتدای کد ها قرار میدهم
    ini_set(session.save_path, ‘test’);
    لطفا راهنمایی میکنید ممنون

    پاسخ
    1. حسن شفیعی ۶ مهر ۱۳۹۸

      سلام. ممنون.
      در ابتدا باید آدرس را بصورت مطلق (absolute) وارد کنید تا مشکلی پیش نیاد (فولدر test را باید از قبل ساخته باشید)
      ini_set(session.save_path, ‘/home/user/public_html/test’);
      که در بالا میتونید به جای /home/user/public_html/ از ثابت هایی مثل DOCUMENT_ROOT برای دریافت مسیر اصلی روی هاست استفاده کنید
      همچنین برای امنیت همیشه بهتر است که سیشن خارج از فولدر قابل دسترس از طریق url یعنی قبل از public_html قرار بگیرد (در پنل های مختلف این public_html با نام های www یا httpdocs شناخته می شود)
      مورد بعدی هم اینکه چون این تابع متغییر های محیطی php که در php.ini هستند را تغییر می دهد و یک مورد امنیتی هست بیشتر هاستینگ ها این قابلیت ساخت و تغییر ini سفارشی را در اختیار مشتریان هاست اشتراکی قرار نمی دهند که از هاستینگ هم میتونید بپرسید.
      موفق باشید.

      پاسخ
      1. sahel ۷ مهر ۱۳۹۸

        ممنون از پاسختون یعنی بهتر است من یک پوشه قبل از پوشه اصلی سایت مثلا httpdocs ایجاد کنم ؟

        پاسخ
      2. حسن شفیعی ۷ مهر ۱۳۹۸

        خواهش می کنم.
        بله

        پاسخ
  5. امید ۱۷ مرداد ۱۳۹۷

    عالی بود مرسی از اموزشتون

    پاسخ
    1. حسن شفیعی ۱۷ مرداد ۱۳۹۷

      سلام. خوشحالم که مفید واقع شده . موفق باشید

      پاسخ
  6. سروش ۲۵ تیر ۱۳۹۷

    عاااااالي واقعا هم مطالب سايتتون عاليه هم اينكه كامل توضيح ميدين با مثال و اينكه از عكسهاي جالب هم استفاده ميكنين،باشد كه توي هممممه مراحل زندگيتون موفق باشين

    پاسخ
    1. حسن شفیعی ۲۵ تیر ۱۳۹۷

      سلام . ممنون خوشحالم که مورد رضایت شما دوست عزیز قرار گرفته . همچنین همیشه موفق و پیروز باشید.

      پاسخ
  7. ماتادور ۱۵ فروردین ۱۳۹۷

    سلام خسته نباشيد
    يكي از بحث هاي امنيتي آپلود عكس يا فايل توسط كاربر هستش
    خيلي تو نت مي گردم ولي هر راهكاري يه روش گرد كردن توسط هكر داره
    تو سامانه من وقتي كاربر عكسي آپلود مي كنه تو كل سيستم مي چرخه
    نمي تونم با ايزوله كردن فولدر آپلود حل كنم
    حتما بايد فايل تميز وارد سيستم بشه
    راهكاري برأي چك كردن فايل وجود داره؟

    پاسخ
    1. حسن شفیعی ۱۵ فروردین ۱۳۹۷

      سلام . ممنونم .

      بله کافیه یک آرایه از mime-type های قابل قبول مثلا برای تصویر image/jpeg , image/png و .. تعریف کنید و بعد با in_array کنترل کنید که البته به تنهایی نباید استفاده بشه چون با افزونه هایی مثل live http header و یا tamper data قابل دور زدنه.

      مرحله دوم چک کردن پسوند فایل است که با تابع pathinfo باید چک کنید.
      و مرحله سوم چک کردن یک سری از کد ها مثلا

      پاسخ
  8. حمیدرضا ۲۵ اسفند ۱۳۹۶

    سلام مجدد
    اگر ما آدرسی مانند https://example.com/test.php?color=red باز کنیم با توجه به اینکه دامنه از ssl استفاده می‌کنه پس باید رمزگذاری انجام بشه ولی ما در سمت سرور به راحتی با آرایه $_GET به داده‌هایی که در کوئری استرینگ ست میشن دسترسی داریم.
    پس باید نتیجه این باشه که ssl داده‌های کوئری استرینگو رمزنگاری نمیکنه درسته؟
    ممنون.

    پاسخ
    1. حسن شفیعی ۲۵ اسفند ۱۳۹۶

      سلام .
      اطلاعات در URL‌رو شما میتونید با روش های دیگه ای مثل اینکودینگ های مختلف امن نگه دارید ولی همانطور که می دونید به هیچ وجه نباید اطلاعات حساس مثل پسورد ها و توکن ها رو در url قرار بدید چرا که ssl در لایه Transport در HTTP کار میکنه و اطلاعات POST رو اینکریپت میکنه و اگر مقدار خاصی در URL پاس نمی دید نیازی به اینکود کردن اونها هم نیست .

      موفق باشید.

      پاسخ
  9. حمیدرضا ۲۵ اسفند ۱۳۹۶

    سلام حسن آقا
    مطلبت عالیه خیلی استفاده می‌کنم از مطالب سایتت.
    خدا خیرت بده.

    پاسخ
    1. حسن شفیعی ۲۵ اسفند ۱۳۹۶

      سلام . خوشحالم که مفید واقع شده .
      مرسی . موفق و پیروز باشید.

      پاسخ
  10. زهره ۱۹ آبان ۱۳۹۶

    ممنون از مقاله مفیدتون

    پاسخ
    1. حسن شفیعی ۱۹ آبان ۱۳۹۶

      خواهش می کنم . خیلی خوشحالم که مفید واقع شده .
      موفق و پیروز باشید

      پاسخ
دوره های آموزشی

دانلود رایگان کتاب آموزش PHP

صفر تا صد PHP و MySQL را یکجا یاد بگیرید
همین الان دانلود کن
نگران نباشید. ایمیل‌های مزاحم نمی‌فرستیم
close-link