انواع آسیب پذیری در PHP - چک لیست بررسی باگ در کد

در نوشته های قبلی در مورد مبانی امنیت برنامه‌های تحت وب و امنیت در PHP توضیحاتی رو ارائه دادم. در این پست قصد دارم نکات و آسیب پذیری‌هایی را که هنگام نوشتن کدهای PHP، امکان رخ دادنشان هست و نیاز به توجه و حساسیت بیشتری از جانب برنامه نویسان و توسعه دهندگان دارد را توضیح دهم.زبان PHP محبوب‌ترین زبان برنامه نویسی سمت سرور است. بر اساس داده‌های سایت W3Techs در سال ۲۰۱۹، ۷۹ درصد از وب سایت‌ها، قدرت گرفته از PHP هستند. از آنجایی که PHP زبان محبوبی است، امنیت در PHP امری ضروری است. متاسفانه تعداد برنامه‌های آسیب پذیر نوشته شده با PHP بسیار زیاد است.منابعی که این آسیب پذیری‌ها را شرح دادن اکثرا از mitre.org و OWASP هستند. اگر فرصتی باشه در مورد هر کدام از این آسیب پذیری‌ها در پست‌های جداگانه‌ای توضیحات بیشتری ارائه میدم. این نکته رو هم بگم که بعضی از آسیب پذیری‌ها انواع مختلفی دارند. ولی از آنجایی که هدف این پست تنها معرفی گونه‌های مختلف آسیب پذیری است، در اینجا ذکر نشدن. این پست فقط برای برنامه نویسان PHP نیست و می‌تواند برای همه برنامه نویسان وب مفید باشد. ممکن است خیلی از آسیب پذیری‌ها را فراموش کرده باشم که در این پست بیارم، اگر شما هم آسیب پذیری غیر از این موارد می‌شناسید و یا ایرادی می‌بینید خوشحال میشم تو نظرها اعلام کنید تا اعمال کنم. نکته بعدی اینکه، قطعه کدهایی که در زیر آسیب پذیری‌ها آورده شده، نمونه کدآسیب پذیر است و نباید به این فرم در برنامه استفاده شود. برای یادگیری نحوه صحیح نوشتن و جلوگیری از حمله، می‌توانید از مراجع کمک بگیرید. آسیب پذیری در برنامه‌های تحت وب به ۴ دسته تقسیم می‌شود: Medium, High, Critical و Low:۱. آسیب پذیری‌های با درجه اهمیت Critical آسیب پذیری‌هایی با درجه اهمیت حیاتی که معمولا برای اکسپلویت کردنشان نیاز به استفاده از تکنیک‌های مهندسی اجتماعی نیست و می‌تواند منجر به آسیب دیدن زیرساخت و یا از دست رفتن اطلاعات حساس شود. در ادامه آسیب پذیری‌های این دسته رو به صورت مختصر توضیح میدم.Command Injectionاین حمله زمانی اتفاق می‌افتد که داده ورودی به عنوان یک دستور سیستمی تفسیر و اجرا شود:$file=$_GET['filename']; system(&quotrm $file&quot);SQL Injectionزمانی رخ می‌دهد که داده ورودی به عنوان یک دستور SQL، تفسیر و اجرا شود:$articleid = $_GET['article']; $query = &quotSELECT * FROM articles WHERE articleid = '$articleid'&quotCode Injectionزمانی زخ می‌دهد که داده ورودی به عنوان یک کد PHP، تفسیر و اجرا شود:$myvar = &quotvarname&quot $x = $_GET['arg']; eval(&quot\$myvar = \$x;&quot);Arbitrary File Writeزمانی که مهاجم بتواند هر فایل با هر پسوند دلخواهی را در سرور بارگذاری یا ایجاد کند این حمله صورت می‌گیرد:$target_dir = &quotuploads/&quot $target_file = $target_dir . basename($_FILES[&quotfileToUpload&quot][&quotname&quot]); if(isset($_POST[&quotsubmit&quot])) { move_uploaded_file($_FILES[&quotfileToUpload&quot][&quottmp_name&quot], $target_file)}Remote File Inclusionبا استفاده از include برنامه نویس قادر است تا یک فایل php را گرفته و از کدهای آن در فایل جاری استفاده کند. حالا چه اتفاقی می‌افتد اگر این فایل، یک فایل مخرب باشد:$file = $_GET['file']; include($file);Object Injectionاین آسیب پذیری هم زمانی رخ می‌دهد که ورودی کاربر قبل از آنکه sanitize شود در اختیار تابع unserialize قرار گیرد:$user_data = unserialize($_GET['data']);۲. آسیب پذیری‌های با درجه اهمیت High آسیب پذیری‌های این دسته معمولا اکسپلویت کردنشان سخت‌تر از دسته Critical است. مهاجم بعد از کسپلویت، می‌تواند سطح دسترسی خودش رو در سیستم افزایش، بخشی از داده‌ها را سرقت و یا باعث از کار افتادن سیستم شود.Local File Inclusionشبیه آسیب پذیری File Inclusion است. با این تفاوت که مهاجم فقط قادر به اجرای فایل‌های محلی در سرور است: $file = $_GET['file']; include('directory/' . $file);LDAP Injectionاِلدَپ یک پروتکل در لایه کاربرد، برای ارتباط با دایرکتوری سرویس است. در صورتی که ورودی کاربر sanitize نشود مهاجم قادر است که اطلاعات موجود در LDAP را مشاهده، تغییر و یا دستور مد نظرش را اجرا کند:class LDAPAuthenticator { public $conn; public $host; function __construct($host = &quotlocalhost&quot) { $this->host = $host; } function authenticate($user, $pass) { $result = []; $this->conn = ldap_connect($this->host); ldap_set_option( $this->conn, LDAP_OPT_PROTOCOL_VERSION, 3 ); if (!@ldap_bind($this->conn)) return -1; $result = ldap_search( $this->conn, &quot&quot, &quot(&(uid=$user)(userPassword=$pass))&quot ); $result = ldap_get_entries($this->conn, $result); return ($result[&quotcount&quot] > 0 ? 1 : 0); } } if(isset($_GET[&quotu&quot]) && isset($_GET[&quotp&quot])) { $ldap = new LDAPAuthenticator(); if ($ldap->authenticate($_GET[&quotu&quot], $_GET[&quotp&quot])) { echo &quotYou are now logged in!&quot } else { echo &quotUsername or password unknown!&quot } }Path Traversalاشاره به یک نوع حمله، که بخاطر sanitize نکردن ورودی، مهاجم را قادر می‌سازد که به فایل‌های غیر از آنچه برنامه نویس انتظار دارد دسترسی داشته باشد:$file = $_GET['file']; file_get_contents('directory/' . $file);Integer Overflowزمانی رخ می‌دهد که در محاسبات اعداد، خروجی با چیزی که برنامه نویس انتظار دارد تفاوت داشته باشد. مثلا در جمع عدد ۱ با 9223372036854775807 ، انتظار می‌رود که حاصل یکی بیشتر شود، ولی در عمل اینگونه نیست. البته این مشکل در زبان‌هایی مثل C و C++ نمود بیشتری دارد.var_dump(PHP_INT_MAX+1); //float(9.2233720368548E+18)Type Confusionزمانی که دو مقدار را با هم مقایسه می‌کنید، PHP نوع آنها را حدس و بر اساس آن مقایسه رو انجام می‌دهد. PHP یک زبان داینامیک است و معمولا به صورت خودکار بر روی داده‌ها تغییر نوع انجام می‌دهد. در کد زیر انتظار می‌رود که خروجی به ما False دهد، ولی اینگونه نیست:var_dump(&quot0&quot == &quot-0&quot);Phar Deserializationاین آسیب پذیری اولین بار در سال ۲۰۱۸ و در کنفرانس Black Hat معرفی شد. مشابه Object Injection است، با این تفاوت که نیازی به تابع unserialize برای اجرا ندارد. ولی نیاز به یک سری شرایط مثل تعریف magic methodها دارد که اگر فرصت کنم توی پست‌های بعدی مفصل‌تر توضیح میدم. مثال زیر دارای آسیب پذیری از این نوع است:class AnyClass { function __destruct() { echo $this->data; } } include('phar://test.phar');۳. آسیب پذیری‌های با درجه اهمیت Medium آسیب پذیری‌های این دسته معمولا برای بهره برداری نیاز به استفاده از تکنیک‌های مهندسی اجتماعی دارند. معمولا بعد از اکسپولیت تاثیر کمی برو روی کسب و کار سازمان می‌گذارند. اکسپلویت کردن آنها معمولا مشکل است. یا اینکه نیاز به سطح دسترسی خاصی دارند.Arbitrary File Deletionزمانی رخ می‌دهد که به کاربر اجازه دهیم فایل دلخواهی را حذف کند:unlink($_GET($file));Data Manipulationگاهی اوقات مهاجم نیازی به سرقت داده‌ها ندارد. با دستکاری داده‌ها، به آنچه نیاز دارد، می‌رسد.نباید به مهاجم اجازه دهیم تا محتویات فایل یا داه ای را تغییر دهد.Cross-Site Scripting (XSS)یک نمونه از حملات تزریق کد است که مهاجم کدهای مخرب خود را در یک وب سایت مطمئن تزریق می‌کند. هدف این گونه حملات، بازدیدکنندگان سایت است.print &quotNot found: &quot . urldecode($_SERVER[&quotREQUEST_URI&quot]);XQuery Injectionزبان XQuery (XML Query)، یک پرس و جو بر روی داده های ساخت یافته و غیر ساخت یافته مانند XML و فایل‌های متنی است. در این نوع حمله، مهاجم قادر به تغییر مفهوم پرس و جو است:$memstor = InMemoryStore::getInstance(); $z = Zorba::getInstance($memstor); try { // get data manager $dataman = $z->getXmlDataManager(); // load external XML document $dataman->loadDocument('users.xml', file_get_contents('users.xml')); // create and compile query $express = &quotfor \$user in doc(users.xml)//user[username='&quot . $_GET[&quotusername&quot] . &quot'and pass='&quot . $_GET[&quotpassword&quot] . &quot'] return \$user&quot $query = $zorba->compileQuery($express); // execute query $result = $query->execute(); XPath Injectionزبان XPath یک پرس و جو برای انتخاب نود‌ها در یک سند XML است . این آسیب پذیری زمانی رخ می‌دهد که داده‌های ورودی از کاربر بدون sanitize کردن در در یک پرس و جو قرار داده شود:&quot//Employee[UserName/text()='&quot & $_GET['UserName'] & &quot' And Password/text()='&quot & $_GET['Password'] & &quot']&quotReflection Injectionاین آسیب پذیری هم زمانی رخ می‌دهد که به اشتباه از Reflection در برنامه استفاده کنید. مهاجم معمولا در صورت وجود این نوع آسیب پذیری قادر به کنترل جریان برنامه و تزریق کد است.XSLT Injectionزبان XSLT مبتنی بر XML است و شیوه تبدیل از یک فایل XML به فایلی دیگر را توصیف می‌کند. در این نوع حمله مهاجم قادر است، ساختار و محتوای یک فایل XML رو تغییر دهد. که منجر به خواندن از یک فایل یا اجرای یک دستور دلخواه می‌شود:$xml = new DOMDocument; $xml->load('local.xml'); $xsl = new DOMDocument; $xsl->load($_GET['key']); $processor = new XSLTProcessor; $processor->registerPHPFunctions(); $processor->importStyleSheet($xsl); echo $processor->transformToXML($xml);XML/XXE Injectionیک نمونه از حملات که هدف آن برنامه ای است که ورودی XML را پردازش می‌کند. زمانی که ورودی XML حاوی یک رفرنس به یک موجودیت خارجی باشد و پیکربندی پردازشگر XML ضعفی داشته باشد، این حمله احتمال رخ دادنش وجود دارد.NoSQL Injectionحمله‌ای مشابه SQL Injection، با این تفاوت که بر روی پایگاه داده‌های NoSQL است.Session Fixationدر این حمله مهاجم یک session id معتبری دارد که کاربر را به سمت استفاده از این session id هدایت می‌کند. در واقع این حمله زمانی رخ می‌دهد که برنامه به جای تولید یک session id جدید در هر بار ارتباط، از یک session id ذخیره شده استفاده کند.Open Redirectاین حمله زمانی اتفاق می‌افتد که برنامه، ورودی را از مهاجم دریافت و به آن تغییر مسیر دهد. این کار می‌تواند کاربر را به یک سایت مخرب هدایت کند:<?php header(&quotLocation: http://www.mysite.com&quot); exit; ?>HTTP Response Splittingاین حمله زمانی رخ می‌دهد که داده‌ از طریق یک منبع نامطمئن مانند HTTP Request به برنامه ارسال شود. و یا اینکه داده ارسال شده به کاربر نهایی، بدون هیچگونه اعتبار سنجی در کاراکترهایش، در HTTP response header قرار گیرد.Variable Tamperingاین حمله زمانی اتفاق که مهاجم با قرار گرفتن در بین کاربر نهایی و سرور، داده‌های ارسالی به سمت سرور را تغییر دهد. حمله Man In The Middle.Mass Assignmentفرآیندی است که آرایه‌ای از داده‌ها را به یک کلاس ارسال می‌کند. یعنی نیاز نیست داده‌ها را یکی یکی ارسال کنیم. مشکلی ک این روش دارد این است که ممکن است مهاجم مقداری را بدون هیچگونه بررسی به این کلاس ارسال و منجر به نقص امنیتی شود. مثال زیر نمونه ای از این آسیب پذیری است:class User { private $userid; private $password; private $email; private $isAdmin; //Getters & Setters }۴. آسیب پذیری‌های با درجه اهمیت Lowاین دسته از آسیب پذیری‌ها اکسپلویت کردنشان مشکل و معمولا نیاز به دسترسی فیزیکی به سرور دارند. همچنین تاثیر کمی بر روی کسب وکار یک سازمان دارند. Server-Side Request Forgeryاین حمله هنگامی رخ‌ میدهد که مهاجم بتواند درخواستی را به سمت سرور ارسال و منابع داخلی سیستم که در حالت عادی امکان دسترسی به آنها از بیرون وجود ندارد، مانند فایل‌هایی پشت فایروال یا تنظیمات پیکربندی را بخواند. در قطعه کد زیر، مشاهده می‌کنید که مهاجم کنترل کاملی روی پارامتر url دارد:<?php if (isset($_GET['url'])){ $url = $_GET['url']; $image = fopen($url, 'rb'); header(&quotContent-Type: image/png&quot); fpassthru($image);}Memcached Injectionاز Memcached برای انجام عملیات کش بر روی سرور به صورت داینامیک استفاده می‌شود. ولی در صورت استفاده نادرست می‌تواند منجر به نقص امنیتی شود. قطعه کد زیر این آسیب پذیری رو نشان می‌دهد:<?php $m = new Memcached(); $m->addServer('localhost', 11211); $m->set(str_repeat(“a”,251),&quotset injected 0 3600 10\r\n1234567890&quot,30);?>Resource Injectionمشابه حمله Path Traversal، با این تفاوت که تمرکز اصلی آن دسترسی به منابع سیستم است. در مثال زیر نام فایل موقت از کاربر گرفته شده و سپس حذف می‌شود. ولی یک مهاجم با وارد کردن آدرس یا نام منبعی غیر از آنچه برنامه نویس انتظار دارد، موجب حذف شدن آن منبع می‌شود:<?php $rName = $_GET['fileId']; $myfile = fopen('/log/'.$rName, &quotr&quot); unlink($myfile)?>Environment Manipulationاین آسیب پذیری از آنجا ناشی می‌شود که یک مهاجم بتواند به پیکربندی سیستم دسترسی و آنرا تغییر دهد.HTTP Parameter Pollutionاین آسیب پذیری زمانی رخ می‌دهد که برنامه چندین پارامتر با نام یکسان را پذیرش کند. زمانی که این داده‌ها به سرور ارسال می‌شوند، با توجه به تنظیمات و پیکربندی سرور، این داده‌ها به طرق مختلف پردازش می‌شوند. مثلا در سرور آپاچی تنها آخرین پارامتر پردازش می‌شود. مهاجم با بهره برداری از این آسیب پذیری قادر به تغییر رفتار برنامه و حتی دور زدن WAF است.Weak Cryptographyاین آسیب پذیری از آنجا ناشی می‌شود که برای انجام عملیاتی مثل رمزنگاری فایل‌ها و داده‌ها، تولید هش، ایجاد اعداد تصادفی و غیر قابل حدس و ... از الگوریتم‌های ضعیف یا منسوخ شده استفاده کنیم. برای مثال قطعه کد زیر تابعی برای تولید اعداد تصادفی جهت رمزنگاری است. ولی ایراد آن این است که مقادیر تکراری تولید می‌کند و مناسب رمزنگاری نیست: function gen_uuid() { return sprintf( ' x x- x- x- x- x x x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ));}در انتها جا داره دوباره بگم که این لیست کمبود‌های زیادی داره و جمع آوری این لیست حاصل تجربه شخصی خودم در بررسی کدهاست. اگر شما هم پیشنهادی دارید توی نظرها بگید تا اعمال کنم. اگر بتوانم و وقت کنم بعدا همچین پستی برای زبان‌های دیگه مثل پایتون، جاوا و سی هم می نویسم.