ترفند امنیتی برای php

+۱۵ ترفند امنیتی برای بالا بردن امنیت برنامه PHP شما – قسمت دوم

۶- به رمزهای عبور نمک بزنید! و از رمزنگاری های قدرتمند استفاده کنید:
MD5 یکی از محبوب ترین الگوریتمهای رمزنگاری مورد استفاده توسط برنامه نویسان php است. تابع md5 داده رمزنگاری شده را به درستی برمیگرداند:

هرچند که، تابع md5 روش کاملا مطمئنی برای رمزنگاری نیست. اکثر کاربران تمایل دارند از رمزهای عبور ۵،۶ کاراکتری استفاده کنند، رمزهای عبور به این شکل که از پیچیدگی مناسبی برخوردار نیستند، توسط یک حمله brute-force  (جستجوی فراگیر) ساده نیز  آسیب پذیر خواهند بود. حتی ممکن است اصلا نیازی به حمله brute-force نباشد و فقط یک جستجوی ساده ی عبارت رمزنگاری شده (hash) در گوگل، رمزعبور را در نتایج وبسایتهای تخریبگر رمزعبور نشان دهد! و شاید بازهم ساده تر از این باشد. بنابراین، این کافی نیست که فقط به کابر بگویید رمزعبور پیچیده تر انتخاب کند.

برای اینکه این مشکل حل شود، برنامه نویسها از نمک (Salt) استفاده میکنند. منظور از نمک زدن به پسوردها، اضافه کردن یک عبارت نا مفهوم به پسوردها قبل از رمزنگاری آنها است که به صوت تصادفی تولید شده، و تکرار همین کار زمان مقایسه پسورد وارد شده توسط کاربر، با پسورد رمزنگاری شده ی موجود در پایگاه داده است.

اضافه کردن نمک (عبارت اضافی) به رمز عبور، طول آن را افزایش داده و باعث پیچیدگی آن میشود . بنابراین زمان مورد نیاز برای یافتن رمز با روش حمله جستجوی فراگیر، بسیار افزایش میابد و در واقع ناممکن میشود.

همراه با نمکپاشی، بهتر است از الگوریتمهای رمزنگاری طولانی تر (ولی کندتر) مانند sha1 , sha2  و … استفاده کنید. این نوع رمز نگاری چون زمان زیادی میبرد، برای مقابله با حملات جستجوی فراگیر مناسب است.

** پیوست :

یک تابع دیگر در php برای این منظور تابع crypt میباشد:

خود من هم از این روش برای رمزنگاری استفاده میکنم:

نمونه افزودن نمک که در وردپرس بکار رفته:

 

۷- محافظت در برابر درخواستهای جعلی (CSRF):
CSRF مخفف عبارت Cross Site Request Forgery به معنی درخواستهای جعلی از سایت دیگر میباشد. این نوع آسیب پذیری نامشخص ترین نوع آسیب پذیری است چرا که اصلا به صورت یک مشکل به نظر نمیرسد. بیایید url ای را در نظر بگیریم که در پایگاه داده تغییر ایجاد میکند:

مشکل url بالا در این است که اگر هکر همچین url ای را با دسترسی کاربر بدون اطلاع وی بتواند اجرا کند چه اتفاقی می افتد؟

هکر لینک بالا را در لینک مسیر یک تصویر در سورس کد صفحه وب مربوط به خود (hackersite.com/interesting.html) قرار میدهد و از کاربر میخواهد وبسایت او را باز کند:

حالا چون کاربر در برنامه شما لاگین نموده است (logged in) پس از باز نمودن صفحه مربوط به هکر url بالا هنگام لود تصویر فراخوانی میشود. و این یک درخواست قانونی است.

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

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

راه حل قوی تر و عمومی تر، فعال کردن سرویس جهت شناسایی هر درخواست با یک کلید است. فرم ها میتوانند دارای فیلد مخفی حاوی یک عبارت تصادفی باشند که در session کاربر ذخیره شود و برای تشخیص ارسال فرم بکار روند. کد صفحه مربوط به فرم:¹

کد مربوط به اسکریپت پردازشگر:¹

حالا اگر هکر بخواهد درخواستی را که حاوی مقدار کلید نمیباشد از طرف کاربر واقعی اجرا کند، حمله CSRF او با شکست مواجه میشود.

 

۸- بازسازی Session ID :
session id  را به صورت زیر میتوان بازسازی کرد:

session id حداقل باید در موارد زیر بازسازی شود:
– زمانی که کاربر وارد میشود (Log in)
– زمانی که کاربر خارج میشود (Log out)
– زمانی که کاربر وارد محیط مدیریتی میشود و یا سطح دسترسی کاربر تغییر میکند

شاید بخواهید session id را هر ۱۵ دقیقه یا از هر ۱۰۰ درخواست تغییر دهید:

 

۹- قفل کردن عامل کاربری در طول یک نشست (session):
این روش میتواند از ربودن (hijacking) نشست جلوگیری کند. این روش به این صورت است که تست میکنیم تا ببینیم آیا عامل کاربری (user agent) کاربر تغییر کرده است یا خیر. اگر تغییر کرده باشد، خارج شده (log out) و از کاربر درخواست ورود (log in) میکنیم:

و یا بهنر از آن:

قفل IP روی session :
اگر امنیت بیشتر و قوی تری مورد نیاز است، میتوان آدرس IP کاربر را بر روی session  او قفل کرد:

 

۱۰- ذخیره نشستها (sessions) در پایگاه داده:
به صورت پیشفرض نشستها در فایل ذخیره میشود. تعداد زیادی برنامه وب بر روی میزبانهای اشتراکی (shared hosting) میزبانی میشوند که فایلهای نشستهای آنها در شاخه tmp/ ذخیره میشود. اگر این فایلها رمزنگاری نشده باشند، احتمالا برای کاربران دیگر قابل مشاهده خواهد بود:

برای جلوگیری از مشکل، راه حلهای متعددی وجود دارد. یکی از این روشها استفاده از رمزنگاری اطلاعات نشستها با suhosin است.

ذخیره نشستها در پایگاه داده. در صورت ذخیره نشستها در پایگاه داده، اطلاعات نشستها دیگر همانند فایلها قابل رویت نخواهد بود و فقط برنامه ای که آن را استفاده میکند به آن دسترسی خواهد داشت.

 


¹. Zend PHP 5 Certification STUDY GUIDE

 

قسمت اول | قسمت دوم | قسمت سوم


نظر شما چیه؟

۵ دیدگاه

  1. علیرضا معظمی

    سلام
    خواستم سه نکته تلگرافی بگم چون در امنیت وب یه مقدار مطالعه داشتم؛
    ۱٫ فقط تعداد بسیار بیشتر حالات sha1 (که منجر به کاهش حملات brute force و مهندسی معکوس از طریق lookup table میشه) باعث امنیتش نسبت به md5 نشده.
    وقتی میگن یه الگوریتم (مثلا Md5 شکسته شده) به این معنیه که با حملات «رنگین کمان» (rainbow) و «روز تولد» و … می‌تونن ابتدا سریع‌تر و بدون امتحان کردن همه حالات، بشکننش. اینکه میگم سریع‌تر؛ شاید برای کامپیوترهای ساده‌ی ما هنوز چندماه طول بکشه اما کسی که می‌خواد یه هش رو بشکنه و براش مهمه (مثل هکرای خارجی که یه سرور مهم رو هک میکنن) یه سوپرکامپیوتر رو یه هفته اجاره میکنه مثلا ۱۵۰۰ دلار و میشکنش!
    لذا اینکه شما دلیل امن‌تر بودن sha1 آن نسبت به md5 را زمان اختصاص یافته برای تولیدش ذکر کردید، حرف کاملی نیست. گذشته از اینکه در یک سیستم لاگین امن، بعد از چندبار ورود اشتباه پسورد، معمولا برنامه باید قفل کنه تا مدتی معین.
    ۲٫ (اینو متخصصین امنیت میگن و دلیل علمی‌ش رو نمی‌دونم) دوبار هش کردن (که شما در مطلبتون اشاره کردید) موجب کاهش امنیت رمز عبور میشه.
    ۳٫ برای جلوگیری از حملات CSRF روشهای بهتری هست که بد نیست اشاره کنید:
    الف) چک کردن صفحه ارجاع دهنده
    ب) افزودن کلید به لینک دیلیت (شما فقط به فرم اشاره کردید)
    ج) انجام اعمال مدیریتی با روش post

    • فؤاد طهماسبی نویسنده

      سلام، خیلی ممنون از اینکه اطلاعاتتون رو با ما به اشتراک گذاشتید.
      بله شما درست میفرمایید. مطمئنا هیچ مطلب یا نوشته ای نمیتونه به طور کامل امنیت php رو پوشش بده! این مطلب صرفا جهت آشنایی با روشهای امنیتی و ایجاد دید کلی در این مورد هست. و برای مطالعات بیشتر لینکهایی در انتهای مطلب قرار داده شده.

متاسفانه امکان ارسال دیدگاه وجود ندارد!