بهترین شیوه های امنیتی در PHP


زبان برنامه نویسی PHP یکی از محبوب ترین زبان ها است که امروزه مورد استفاده قرار می گیرد. این زبان توسط میلیون ها وب سایت، از جمله برخی از بزرگترین نام ها در اینترنت استفاده می شود. در حالی که PHP یک زبان بسیار قدرتمند است، اما اگر به درستی استفاده نشود، می تواند کاملاً ناامن باشد. در این پست وبلاگ، روش های برتر برای امنیت PHP را مورد بحث قرار خواهد گرفت که به حفظ وب سایت شما در برابر هکرها و کاربران مخرب کمک می کند.

سعی شده است در این مقاله از مثال های بسیار ساده استفاده شود تا افراد مبتدی نیز در ابتدای کار درک درستی از مطلب پیدا کنند.

۱- بروز رسانی منظم PHP

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

۲- مراقب حملات XSS باشید (Cross-site scripting)

یک حمله XSS زمانی رخ می دهد که یک برنامه وب، external remote code را اجرا می کند. یک مثال خوب زمانی است که کاربر در فرم ورودی، HTML، جاوا اسکریپت یا CSS را وارد می کند و کدها مستقیماً در یک صفحه وب نمایش/اجرا می شود. این اجرای کد می تواند باعث اختلال در عملکرد صفحه یا نمایش نتایج ناخواسته شود.

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

اگر برای چاپ مقدار ورودی، این تابع PHP را فراخوانی کنید:

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

وقتی اسکریپت اجرا می‌شود، «This site hacked by…» به‌عنوان یک پیام هشدار در مرورگر برای کاربر نمایش داده خواهد شد.

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

از حملات XSS می توان با موارد زیر جلوگیری کرد:

  • فیلتر کردن تمام ورودی های کاربر در بدو ورود برای حذف تگ های کد احتمالی از ورود به سایت. کتابخانه htmlpurifier میتواند در این مورد به شما کمک کند.
  • برای جلوگیری از تفسیر داده های ورودی کاربر به عنوان محتوای فعال در پاسخ های HTTP تمام آن را Encode کنید. ( استفاده از توابع htmlspecialchars و htmlspecialchars_decode )

۳- مراقب دستورات SQL باشید

هیچگاه ورودی ها را به صورت مستقیم به دستورات SQL اضافه نکنید و سعی شود از ORM ها استفاده کنید تا مقادیر را بررسی و اجرا کنند

مثال بالا از ورودی کاربر به صورت مستقیم در داخل کوئری SQL استفاده شده است و این به هکر فرصتی می دهد تا query را بشکند و سعی کند اطلاعات دیگر را اجرا کند.

کوئری آماده شده زیر تضمین می کند که تمام مقادیر وارد شده escape شده و هیچ جایی برای تزریق SQL باقی نمی گذارد.

نکته : راه دیگر استفاده از PDO_MYSQL است.

۴− تمام فایل های یک framework یا کتابخانه را آپلود نکنید

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

یک نمونه،‌ در برخی از پروژه های php از یک کتابخانه جاوا اسکریپتی برای ادیتور CKEditor و… استفاده میشود که همراه با نمونه کدهای php برای آپلود فایل و تصاویر است. در آپلود چنین کتابخانه هایی با دقت عمل نمایید و هرگونه فایل php در آنها را حذف کنید.

۵− محدودیت دسترسی به دایرکتوری ها

محدود کردن دسترسی به دایرکتوری را می توان با استفاده از تابع open_basedir انجام داد.

به عنوان مثال، اگر تابع open_basedir روی root پروژه تنظیم شده باشد، به این معنی است که فایل‌های قابل دسترسی تنها فایل‌هایی هستند که در ریشه پروژه شما و به سمت پایین هستند.

۶− پیکربندی SSL خود را verify کنید

فرم هایی که کاربران در وب سایت شما تکمیل و ارسال میکنند،‌ آدرسهایی که پیمایش میکنند و.. همگی به صورت plain text به سرور شما ارسال میشوند. در این مسیر هر شخصی که شبکه sniff کند میتواند محتوای فرم ها و… را به دست آورد. ( یک نمونه فرم ورود کاربر با رمز عبور است ) برای جلوگیری از این موضوع می‌توانید یک گواهی ssl تهیه کرده و در سرور خود برای وب سایت خود نصب نمایید. با نصب و فعال سازی یک ssl تمامی داده ها رمزنگاری شده و فقط توسط وب سرور شما قابل decrypt است و مهاجم در بین راه نمیتواند به داده های شما دسترسی پیدا کند

گواهینامه های SSL را به طور منظم verify کنید و قبل از منقضی شدن تمدید نمایید.

۷- از include کردن فایل های remote خودداری کنید

از پذیرش ورودی کاربر برای include کردن فایل خودداری کنید. این به این دلیل است که مهاجم می‌تواند مسیری را وارد کند که به اطلاعات حساس منتهی می‌شود، به‌عنوان مثال، etc/passwd/ ../../..، که می‌تواند منجر به دسترسی آنها به رمز عبورها در صورتی که در سرور لینوکس/یونیکس باشد، شود.

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

یک مثال ساده:

− ثبت خطای برنامه

ثبت خطا در توسعه برنامه، هم در محیط های staging و هم در محیط production، بسیار حیاتی است. به دلیل این واقعیت که گزارش های خطا به اشکال زدایی و نظارت بر عملکرد برنامه کمک می کند. بنابراین، باید گزارش‌ها را از برنامه‌های PHP در یک فایل مشخص برای استفاده بعدی ذخیره کنید. لاگ ها را به صورت زیر در داخل فایل php.ini پیکربندی کنید:


برای جلوگیری از دستیابی هکرها به اطلاعات ارزشمند در سایت شما بر اساس خطا، باید نمایش خطاها را در سرور production/staging غیرفعال کنید. پارامترهای زیر را در فایل php.in تنظیم کنید:

پیشنهاد میگردد برای سهولت در انجام عملیات ثبت خطا ها از ابزارهایی مانند sentry یا newrelic استفاده نمایید.

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

تمام ورودی های کاربر باید قبل از اینکه توسط کد PHP شما پردازش شود، تأیید شود. این شامل داده‌های وارد شده در فیلدهای فرم، پارامترهای URL و مقادیر JSON می‌شود. با اعتبار سنجی ورودی کاربر، می‌توانید از حملات Cross-Site Scripting (XSS) و دیگر انواع ورودی‌های مخرب جلوگیری کنید.

۱۰- امن کردن دایرکتوری های آپلود فایل و Asset ها

یکی از روش هایی که میتواند دست مهاجم را برای اجرای کدهای آپلود شده خود ببندد،‌ محدودیت اجرای فایل در دایرکتوری هایی است که فرم های اپلود شما،‌فایلها را در آنجا آپلود میکنند یا فایل های asset کتابخانه ها قرار دارد.

تکه کد زیر در nginx میتواند از اجرای فایل های php در دایرکتوری های uploads و assets را بگیرد

شما میتوانید به دلخواه تغییر دهید و اگر از وب سرور آپاچی استفاده میکنید تکه کد زیر را در .htacess قرار دهید

۱۲− غیرفعال سازی توابع خطرناک در php

در php توابعی وجود دارند که میتوان با استفاده از آنها دستوراتی را در سطح سیستم عامل اجرا کرد. مهاجمان معمولا پس از پیدا کردن رخنه‌ی امنیتی برای آپلود فایل، فایل های مورد نظر خود را آپلود کرده تا با سرعت و سهولت بیشتری بتوانند عملیات خود را انجام دهند. در این فایل ها معمولا از توابع زیر استفاده شده است که شما میتوانید در php.ini آنها را غیرفعال کرده و دست مهاجم را برای ادامه عملیات مخرب ببندید

لیست :

php_uname,proc_open,proc_get_status,crack_check,crack_closedict, crack_getlastmessage, crack_opendict, psockopen, php_ini_scanned_files, hell-exec, system, dl, ctrl_dir, phpini, tmp, safe_mode, systemroot, server_software, get_current_user, HTTP_HOST, ini_restore, popen, pclose, exec, shell_exec, suExec, passthru, pclose, proc_nice, proc_terminate, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_ctermid, posix_getcwd, posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups, posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getpwnam, posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo, posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times, posix_ttyname, posix_uname, posix_access, posix_get_last_error, posix_getppid, posix_mknod, posix_strerror, posix_access, posix_ctermid, posix_get_last_error, posix_getcwd, posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups, posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix_getppid, posix_getpwnam, posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_initgroups, posix_isatty, posix_kill, posix_mkfifo, posix_mknod, posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsidposix_setuid, posix_strerror, posix_times, posix_ttyname, posix_uname, symlink, rapih, myshellexec, c99_buff_prepare, c99_sess_put,fpassthru,system ,show_source,parse_ini_file

سخن پایانی

این روش ها کامل نیستند به عنوان مثال صحبتی از CSRF و XSRF و Session Hijacking نشده است ولی میتواند تا حدی در امنیت نرم افزارهایی که به زبان php نوشته شده اند کمک کند. شما میتوانید مطالعه خود را برای موارد فوق ادامه دهید و سعی شود موارد امنیتی را همیشه به عنوان یکی از اصول کد نویسی حرفه ای خود در نظر بگیرید.

نکته : فریم ورک های php مانند laravel تا حد زیادی موراد امنیتی مانند csrf، session hijacking و ... را برطرف کرده اند و ابزارهای اعتبار سنجی ورودی کاربران و... را در اختیار شما قرار میدهند ولی بخشی از موارد بالا مربوط به مدیریت سرورها میشود که باید توسط sysadmin ها اعمال شود.