امنیت نرم افزارها و وب سایت های طراحی شده با پی اچ پی
در این مقاله از سری مقالات طراحی وب سایت امنیت سامانههای مبتی بر پی اچ پی را مورد بررسی قرار میدهیم و نشان میدهیم که چگونه میتوان با پی اچ پی سیستم های امن و مورد اعتمادی را توسعه داد.
این مقاله ترجمهای از یک مقالهی انگلیسی است که در سال ۲۰۱۸ منتشر شده است اما از نظر فنی هنوز هم قابل استفاده و استناد است. لازم به ذکر است که این ترجمه، ترجمهی دقیقی از مقالهی منبع نمیباشد و فقط به انتقال مفهوم اکتفا شده است.
نسخههای پی اچ پی
اولین و راحت ترین موردی که باید به آن توجه کنید و در تمامی نرم افزارها علی الخصوص نرم افزارهای آزاد مد نظر است نسخه نرم افزار است که استفاده میکنید.
بهترین ورژن نرم افزار برای استفاده در پروژههای واقعی آخرین ورژنی از نرم است که به صورت استیبل(stable) ارائه شده است.با توجه به این که برخی از سیستم عامل ها از ورژنهای قدیمی پشتیبانی میکنند شما همیشه از ورژنهایی استفاده کنید که وب سایت پی اچ پی از این ورژنها پشتیبانی میکنه و دورهی توسعهی خود را گذرانده اند.
اینجا میتونید لیست ورژنهایی که توسط وب سایت پی اچ پی پشتیبانی میشه و مناسب استفاده در پروژههای واقعی است را ببینید.
مدیریت وابستگیها و کتابخانهها
به طور خلاصه باید بگم برای نصب و استفاده از منابع خارجی از کامپوزر استفاده کنید.
بهترین راهکار برای مدیریت وابستگیهای نرم افزارهای و وب سایت های طراحی شده با پی اچ پی کامپوزر می باشد.
پی اچ پی از راه درستش یک مقاله عالی در مورد شروع استفاده ازکامپوزر منتشر کرده که نحوهی استفاده از کامپوزر در سیستمهایی که با پی اچ پی توسعه داده میشن را به خوبی توضیح داده است.اگر تا حالا از کامپوزر استفاده نکردهاید حتما این مقاله را مطالعه نمائید.
اگر از کامپوزر استفاده نمیکنید به زودی پکیجها یا وابستگیهایی که در ; استفاده کردین منسوخ میشه و اگه بخواین آپدیت کنید باید دستی همه را دانلود و جایگزین کنید که این کار مستلزم زمان میباشد حتی ممکن است بعضی وقتها سیستم شما با مشکل مواجه بشه. پکیج های منسوخ شده شدیدا مستعد آسیب پذیری هستند چون بعد از دانلود و استفاده اصلا به هیچ و جه آپدیت نشده اند.و در نتیجه به راحتی سیستم شما قابل اکسپلویت شدن هست.
اگر از کامپوزر استفاده میکنید کار شما آسان است.
با استفاده از دستور زیر میتونید به راحتی وابستگی های سیستم خود را آپدیت کنید.
composer update
دفت کنید که کامپوز فقط بسته یا پکیج هایی که با پی اچ پی نوشته شده اند را آپدیت میکنه اگه از بستههایی که تو زبان سی نوشته شده اند استفاده میکنید مجبورید از PECL هم استفاد کنید.
بستهها یا پکیج های پیشنهادی
بدون در نظر گرفتن پروژه ای که روی آن کار میکنید قطعا استفاده از این وابسگیها یا پکیجها برای شما سودمند خواهند بود.
roave/security-advisories
پکیج roave/security-advisories با استفاده از پایگاه دادهی FrendsOfPHP تمام وابستگیهای شما را چک میکنه و اگر در پکیجهای استفاده شده آسیب پذیریهای شناخته شدهای وجود داشت به شما اخطار میده.
برای نصب این پکیج با استفاده از کامپوزر از دستور زیر استفاده کنید
composer require roave/security-advisories:dev-master
متناوبا میتوانید فایل composer.lock خود را در آزمایشگاههای sensio آپلود کنید تا اگر از پکیج منسوخ شده در پروژه خود استفاده کرده باشید به شما اطلاع دهد.
vimeo/psalm
Psalm یک ابزار آنالیز استاتیک است که به شما کمک میکنه باگها ممکن را در کدهای خود شناسایی کنید.اگر میخواهید از پی اچ پی ۵ به پایین پشتیبانی کنید میتونید از Phan , PHPStan استفاده کنید چون Psalm فقط از پی اچ پی ۵٫۴ و بعد از اون پشتیبانی میکنه.
استفاده از Psalm راحته نحوه نصب و پیکربندی اون در خطوط زیر میبینید
# Version 1 doesn't exist yet, but it will one day:
composer require --dev vimeo/psalm:^0
# Only do this once:
vendor/bin/psalm --init
# Do this as often as you need:
vendor/bin/psalm
اگر این اولین بار است که از این ابزار در پایگاه دادهی موجود استفاده میکنید ممکن است مشکلات زیادی را گزارش دهد.
صرف نطر از اینکه کدام ابزار تجزیه تحلیل را استفاده میکنید، پیشنهاد ما این است که آن را در (CI) Continuous Integration workflow کاری خود بگنجانید تا بعد از هر تغییر کد اجرا شود.
HTTPS و امنیت مرورگر
خلاصه کلام: HTTPS و هدرهای امنیتی باید تست شوند.
اکنون دیگر دسترسی به وب سایت ها از طریق HTTP نا امن پذیرفته شده نیست. خوشبختانه ، به لطف پروتکل ACME و مرجع صدور گواهینامه Let Encrypt ، دریافت گواهینامه های TLS به صورت رایگان و تمدید خودکار آنها امکان پذیر شده است.
اگر از هاستهای اشتراکی برای وب سایت خود استفاده میکنید اکثر کنترل پنلها امکان فعال سازی ssl را به شما میدهند.
ادغام ACME در وب سرور شما خیلی راحت است.
- Caddy : این وب سرویس اپن سورس به صورت پیشفرض از https استفاده میکند.
- Apache : به زودی به عنوان mod_md در دسترس است. و آموزشهای با کیفیت زیادی در وب و با این موضوع موجود است.
- Nginx : نسبتاً واضح است.
ممکن است به این فکر کنید که”خوب ، من یک گواهینامه TLS دارم. حالا باید ساعت ها تنظیمات را برای امنیت و سرعت دستکاری کنم.”
باید بگویم جواب منفی است! چون موزیلا پشت و تنظیمات ایدهآل را به صورت خودکار برای وب سرور شما تولید میکند.
اگر می خواهید وب سایت شما ایمن باشد ، باید بیچون و چرا از HTTPS (HTTP over TLS) استفاده کنید. استفاده از HTTPS بلافاصله وب سایت و کاربران شما را از چندین نوع حمله (مانند حمله مرد میانی ، شنود دادههای رد بدل شده ، حمله باز پخش و نشست ربایی که خود مشکلات دیگری از جمله جعل هویت کاربران را به وجود میاورد.) را از بین می برد.
هدرهای امن
اگر چه انتقال دادهها با استفاده از HTTP امنیت کاربران شما را تا حد زیادی تامین میکنه اما توصیه میکنیم با استفاده از هدرهای HTTP این امنیت را بیشتر و بیشتر افزایش دهید.
در ادامه هدرهایی که توسط وب سرور تولید و به کاربر ارسال میشن و امنیت وب سایت شما را افزایش میدن را مشاهده میکنید
Content-Security-Policy
- این هدر تمام منابع داخلی و خارجی که توسط مرورگر در وب سایت شما لود میشن را بررسی میکنه و فقط اجازه لود کردن منابعی را به مرورگر میده که شما تعیین کردهاید.
- برای مطالعهی یک راهنمای سریع برای راه اندازی و مدیریت این هدر به CSP-Builder مراجعه کنید.
- برای مطالعه عمیقتر به introduction to Content-Security-Policy headers مراجعه کنید.
Expect-CT
Referrer-Policy
Strict-Transport-Security
X-Content-Type-Options
X-Frame-Options
برای جلوگیری از حمله های click-jacking باید این هدر را فعال نمائید.
این هدر را با DENY مقدار دهی نمائید اگر از frame ها استفاده می کنید با SAMEORIGIN مقدار دهی نمائید.
X-XSS-Protection
این هدر از حملات xss یا Cross Site Scripting (تزریق اسکریپت) جلوگیری میکنه. این هدر را با مقادیر زیر مقدار دهی نمائید.
۱; mode=block
به طور خلاصه اگه از سیستم مدیریت سشنهای خود پی اچ پی برای مدیریت سشنها یا همان نشست ها استفاده میکنید(که توصیه میشه) تابع session_start() را مانند کد زیر فراخوانی کنید:
session_start([
'cookie_httponly' => true,
'cookie_secure' => true
]);
این کد از سرقت کوکیهای شما توسط دیگر کاربران جلوگیری میکنه.
اگر میخواهید در مورد امنیت نشستهای پی اچ پی بیشتر مطالعه نمائید اینجا مراجعه کنید.
ویژگی امنیتی Subresource Integrity یا SRI
اگر از کتابخانه ها یا فریم ورکهای جاوا اسکریپت یا سی اس اس استفاده میکنید احتمالا شما نیز مثل من دوست دارید اونها را از یک CDN لود کنید. این کار مزایای خاص خودش داره.اما مشکلی که از این روش ناشی میشه اینه که اگه CDN هک بشه و کدهایی که شما اونها تو طراحی وب سایت استفاده میکنید توسط مهاجم دستکاری بشه میتونه خسارات جبران ناپذیری داشته باشه.مهندسین امنیت این مشکل را با SRI حل کرده اند.با استفاده از ویژگی SRI مرورگر میتونه فایلهایی که از CDN دانلود و استفاده میکنه را صحت سنجی بکنه و بفهمه که توسط شخص دیگری دست کاری شده یا نه.
ساز و کار این ویژگی اینجوریه که ویژگی integrity تگ script یا تگ link را با کد هش شدهی base64 محتوای درخواستی از cdn مقدار دهی میکنیم وقتی مرورگر محتوای درخواستی را از CDN دریافت میکند محتوای مورد نظر را به کد هش شده تبدیل میکند و با مقدار integrity مقایسه میکند اگر این دو مقدار برابر باشه یعنی این محتوی سالمه و دستکاری ندشه اگه این دو مقدار متفاوت باشه یعنی این محتوی درخواستی شما دستکاری شده است.
در زیر یک مثال واقعی از بوت استرپ میبینید.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
ارتباطات اسناد و انتقال به صفحه جدید
اغلب برنامه نویسها برای باز شدن لینکها در صفحات جدید با استفاده از تگ a از ویژگی target استفاده میکنن و این ویژگی را با _blank مقدار دهی می کنند.این ویژگی تگ a صفحه جدید را در یک تب جدید باز میکنه اما متاسفانه به پیج هدف اجازه میده یه سری از کنترلها را دست بگیره و یه سری کارها با جاوا اسکریپت انجام بده یا همزمان کاربر را به سه صفحه دیگه انتقال بده و یه کارهای خاصی انجام بده.
برای جلوگیری از این مشکلات حتما ویژگی rel را در تگ a با “noopener noreferrer” مقدار دهی نمائید.برای مطالعه بیشتر در مورد مقادیر اینجا کلیک نمائید.
جهت مطالعه بیشتر در مورد این آسیب پذیری اینجا برید.
برای مطالعه یک مقاله به زبان فارسی در این مورد اینجا کلیک نمائید.
توسعه نرم افزار و وب سایتهای امن با پی اچ پی
اگه در ضمینه امنیت نرم افزار تازه کار هستین بهتره اینجا را مطالعه نمائید.
اکثر متخصصان امنیت نرم افزار ،برنامه نویسها را به منابعی مانند OWASP Top 10 ارجاع میدهند که به نظر میرشد خارج از موضوع باشد.
در هر صورت اکثر اسیب پذیریهای رایج میتواند به عنوان نمونههای خاص از مشکلات امنیتی سطح بالا بیان شود.
هدف و فرضیهی ما این است که امنیت را ساده تر و کاربردی تر به کارآموزان حوزهی امنیت نرم افزار آموزش دهیم تا کارآموزان مشکلات امنیتی را درک کرده و نحوهی حل آنها را بیاموزند.
بدین ترتیب آنها را از استفادهی چک لیست های امنیت منع میکنیم.
تعامل با بانک اطلاعاتی
جهت مطاله بیشتر در مورد جلوگیری از تزریق SQL اینجا را ببینید.
اگر دستورات SQL را خوتان مینویسید مطمئن شوید که از دستورات پیشگیرانه مانند استفاده میکنید.برای جلوگیری از تزریق SQL میتوانید از جانگه دارها استفاده کنید و همچنین ورودی هایی که در کوئری های SQL از آنها استفاده میکنید با استفاده از توابع پایگاه داده چک کنید.
برای این که راحت تر و امن در پی اچ پی با پایگاه داده کار کنید میتونید از کتابخانهی EasyDB بهره ببرید.
در زیر یک کد امن و یک کد نا امن را مشاهده میکنید.
/* یک کد نا امن */
$query = $pdo->query("SELECT * FROM users WHERE username = '" . $_GET['username'] . "'");
/* یک کد امن که از تزریق SQL جلوگیری میکنه*/
$results = $easydb->row("SELECT * FROM users WHERE username = ?", $_GET['username']);
لایه های دیگر انتزاعی دیگری از پایگاه داده وجود دارد که امنیت وب سایت یا نرم افزار شما را تامین میکند.(EsayDB از PDO استفاده میکند)
آپلود فایل
آپلود فایل میتونه ریسکهای زیادی به همراه داشته باشه.با این با رعایت برخی اصول اولیه میتوان فایلها را به صورت امن آپلود کرد.به طور مثال میتوان از اجرای فایلهای آپلود شده توسط کاربر جلوگیری کرد.
بدون استثنا فایلهای اجرا شده نباید روی سرور قابل اجرا باشند.همیشه باید دسترسی این فایلها فقط خواندنی یا فقط خواندنی-نوشتنی باشند.
اگر ریشهی وب سایت شما به صورت /var/www/example.com است فایلهای که از توسط کاربرها آپلود میشوند نباید در پوشهی که داخل ریشه است(مثلا /var/www/example.com/uploaded_files) آپلود کنید.
به جای ذخیرهی این فایلها روی پوشهای که داخل ریشهی اصلی است باید آنهای را در پوشه جداگانه ذخیره کنید که دسترسی مستقیم(مثل /var/www/example.com)ندارد.در غیر این صورت ممکن است فایلها به صورت تصادفی اجرا شده سرور شما را برای اجرای کد از راه دور آماده سازند.
یک روش ساده این است که ریشهی وب سایت خود را به یک سطح دیگر انتقال دهید(مثل /var/www/example.com/public) .
مشکل دیگری که در آپلود فایلها ممکنه رخ بده نمایش فایلها به کاربران با خیال راحت است.
- وقتی فایلهای SVG به صورت مستقیم لود میشن میتونن فایلهای جاوا اسکریپت ار در مرورگر کاربر اجرا کنند.وجود پیشوند /image در پیشوند mime تایپ تصاویر SVG برنامه نویس را گمراه میکنید.
- همانطور که قبلا بحث شد تغییر نوع MIME و اپلود فایل میتونه خسارتهای زیادی به بار آورد.جهت مطالعه بیشتر به X-Content-Type-Option مراجعه نمائید.
- اگر توصیههای قبلی را در مورد نحوهی آپلود فایل توسط کاربر را رعایت نکنید یک مهاجم به راحتی میتونه یه فایل از نوع .php یا phtml را روی سرور شما آپلود کرده و سرور شما را از مرورگر خود اجرا کند.
حملات Xss یا Cross Site Scripting
جهت مطالعه بیشتر مورد حملات XSS اینجا را ببینید.
در این روش مهاجم با استفاده از روشهای مختلف اسکریپتهایی به وب سایت تزریق میکند تا موقع بازدید کاربرها روی دستگاه آنها اجرا شود و فرامین دلخواه مهاجم را اجرا کند.
در واقع جلوگیری از آسیب پذیری xss آسان است و همانند جلوگیری از تزریق SQL با رعایت چند نکتهی کوتاه در این مورد نیز وب سایت یا نرم افزار امن خواهد بود.
متاسفانه در دنیای واقعی اکثر توسعه دهندگان وب کدهای html را تولید کرده و در پاسخ درخواستهای HTTP به مرورگر کاربر ارسال میکنند و این محدود به پی اچ پی یا یک زبان خاص نیست.و این با عث میشود مهاجم از هر راهی که بتونه کدهای خود را تزریق و در مرورگر کاربر اجرا کند.با رعایت چند مورد ساده به راحتی میتوان از حملات XSS جلوگیری کرد.
- همیشه داده های خروجی فیلتر نمائید نه موقع دریافت دادهها.چون اگه مهاجم آسیب پذیری دیگری در وب سایت شما پیدا کند میتونه کدهای مورد نظرش را تزریق کنه و ….
- اگر فریمورک شما از موتور تولید قالب HTML پشتیبانی میکنه حتما ازش استفاده نمائید
- اگر در پروژه خود میتونید از Markdown استفاده کیند به جای HTML از مارک داون استفاده نمائید.
- اگه قراره کاربرها در ورودی ها از برخی تگهای html استفاده کنند و شما از موتور تولید قالب استفاده نمیکنید حتما از HTML Purifier استفاده نمائید.
- به کاربرانتان فقط استفاده از url های http , https را بدهید.
- جهت ارسال داده ها به خروجی از تابع htmlentities به صورت زیر استفاده نمائید.
echo htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
در هر صورت با استفاده از نکات زیر میتونید وب سایت یا نرم افزار تحت وب خود را در مقابل تزریق XSS ایمن کنید.
حملات Cross-Site Request Forgery (CSRF)
حملات xss معمولا با رعایت دو نقطه دفع میشن که در زیر به آنها اشاره میکنیم
- استفاده از HTTPS که در اینجا نحوه استفاده از آن را بررسی کردیم.بدون استفاده از SSL اساسا وب سایت شما نام امن خواهد بود و هر اقدامی برای امن سازی آن آب در هاون کوبیدن است.اما توجه نمائید که HTTPS به تنهایی وب سایت شما را در برابر حملات CSRF امن نخواهد کرد.
- دومین کاری که برای جلوگیری از حملات CSRF باید انجام دهید این است که یک تگ html مخفی به فرمها خود اضافه نمائید. و با استفاه از مقادیر کریپتوگرافی که به صورت رندم تولید شده است آن را مقدار دهی نمائید سپس موقع دریافت و پردازش اطلاعات فرم مقدار این فیلد مخفی را کنترل نمائید این فیلد باید مقداری که شما در آن ذخیره کرده بودید برابر باشد.
برای جلوگیری از حملات CSRF میتونید از کتابخانهی Anti-CSRF استفاده نمائید.
اکثر فریم ورکها مثل لاراول و … از تولید CSRF token پشتیبانی میکنند در صورتی که از فریم ورکی استفاده میکنید که از این قابلیت را ندارد میتونید از Anti-CSRF استفاده نمائید.
در آیندهی نزدیک کوکیهای بعضی سایتها در جلوگیری از حملات CSRF به ما کمک خوهند کرد.برای کسب اطلاعات بیشتر در این مورد اینجا کلیک نمائید.
آسیب پذیری XML یا XXE, XPath Injection
دو آسیب پذیری عمده در نرم افزارهایی که پردازش XML زیادی انجام میدهند هست
- تزریق XXE
- ترزیقXPath
—–
حملات تزریق XPath شبیه تزریق SQL می باشند با این تفاوت که این حملات روی فایلهای xml انجام میگیره.
خوشبختانه انتقال اطلاعات ورودی کاربران به یک کوئری XPath در سیستم پی اچ پی بسیار نادر میباشد.
بهترین گزینه برای انتقال داده ها به کوئری XPath استفاده از مجموعهای از کاراکترهایی است که خودتان در لیست سفید قرار داده اید.
<?php
declare(strict_types=1);
class SafeXPathEscaper
{
/**
* @param string $input
* @return string
*/
public static function allowAlphaNumeric(string $input): string
{
return \preg_replace('#[^A-Za-z0-9]#', '', $input);
}
/**
* @param string $input
* @return string
*/
public static function allowNumeric(string $input): string
{
return \preg_replace('#[^0-9]#', '', $input);
}
}
// Usage:
$selected = $xml->xpath(
"/user/username/" . SafeXPathEscaper::allowAlphaNumeric(
$_GET['username']
)
);
امنیت استفاده از لیست سفید بیشتر از لیست سیاه
این یک مقالهی ترجمه شده ی ناقص است که هر روز قسمتی از این مقاله ترجمه میشه.
اگر میتونید در ترجمه این مقاله با من همکاری کنید لطفا در قسمت نظرات اعلام نمائید.
با تشکر امیر حسنزاده.