joomla 5

فصل سیزدهم: اقدامات امنیتی در جوملا

(زمان تقریبی مطالعه: 13 - 25 دقیقه)

بیان خلاصه ای از بحث توسط هوش مصنوعی:

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

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

حتی اگر فکر می کنید که سوء استفاده از یک آسیب پذیری در کد شما غیرممکن است، باید فعال باشید و آن را برطرف کنید. برنامه های کاربردی وب در یک محیط پیچیده با فناوری های زیادی درگیر حرکت می کنند، بنابراین حملات ممکن است به دلایل غیر منتظره ظاهر شوند.

در این فصل، رایج ترین روش های امنیتی را که باید در جوملا دنبال کنیم، پوشش خواهیم داد. این به شما کمک می کند راه حل های ایمن را به کاربران خود ارائه دهید.

در این فصل به موضوعات زیر می پردازیم:

  • واکشی (بررسی) داده ها از فرم ها
  • جلوگیری از تزریق SQL
  • دارایی های خود را برای آینده تضمین کنید
  • سخت شدن دسترسی به فایل های شما

الزامات فنی

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

  • Visual Studio Code (یا ویرایشگر کد دلخواه شما)
  • فایل های کد این فصل را می توانید در GitHub در مسیر زیر بیابید:

 https://github.com/PacktPublishing/Developing-Extensions-for-Joomla-5/tree/chapter13 

واکشی داده ها از فرم ها

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

مشکل زمانی ایجاد می شود که ما تعامل را در توسعه  های خود لحاظ می کنیم، معمولاً فرم  هایی را به صفحات اضافه می کنیم. فرم ها بسیار رایج هستند، حتی برای صفحاتی که قرار است اطلاعاتی مانند فهرست داده ها را نشان دهند. اگر نمای پروژه های Projects ما را به خاطر دارید، یک فرم جستجو و صفحه بندی اضافه کردیم تا پروژه ها را به راحتی در پایگاه داده خود جستجو کنید. آن ویژگی ها، فرم ها هستند. این را می توان در متن زیر از چیدمان پروژه های فهرست شده در backend  در آدرس زیر مشاهده فرمایید:

src/component/admin/tmpl/projects/default.php

 
<form action="<?php echo Route::_('index.php? 
option=com_spm&view=projects'); ?>" method="post" 
name="adminForm" id="adminForm"> 
<div class="row"> 
<div class="col-md-12"> 
<?php echo LayoutHelper::render('joomla.search 
tools.default', ['view' => $this]); ?> 
</div> 
</div> 
... 
</form> 

در این کد، می توانیم تگ  های form  و نحوه فراخوانی چیدمان جستجو برای بارگذاری فیلترهای تعریف  شده در فرم را ببینیم. این کد به یک کادر ورودی جستجوی متن، با معادلHTML ، تمام فیلترهای تعریف شده در src/component/admin/forms/filter_projects.xml  را ترجمه می کند.

این نما همچنین دارای یک بخش صفحه بندی در پایین و یک کادر ورودی برای تغییر تعداد موارد نشان داده شده خواهد بود. همه اینها عناصر HTML هستند که یک کاربر مخرب ممکن است وسوسه شود آنها را اصلاح کند تا حمله ای را به سیستم ما تزریق کند.

بنابراین، در کد خود، هنگام دریافت این مقادیر، هرگز نباید به آنها کاملاً اعتماد کنید و در صورت امکان آنها را فیلتر کنید. همانطور که در فصل 4 مشاهده شد، برای فیلترهای پروژه، مقادیر متدpopulateState  را در مدل دریافت می کنیم. بنابراین، اگر فایلsrc/component/admin/src/Model/projects.php  را بررسی کنید، ممکن است این کد را پیدا کنید:

 
protected function populateState($ordering = 'name', 
$direction = 'ASC') 
{ 
$app = Factory::getApplication(); 
$value = $app->input->get( 
'limit', 
$app->get('list_limit', 0), 
'uint'); 
$this->setState('list.limit', $value); 
$value = $app->input->get('limitstart', 0, 'uint'); 
$this->setState('list.start', $value); 
$search = $this->getUserStateFromRequest( 
$this->context . '.filter.search', 
'filter_search'); 
$this->setState('filter.search', $search); 
parent::populateState($ordering, $direction); 
} 

در PHP، مقادیری که از طریق یک فرم ارسال می شوند، در متغیر جهانی$_POST  ذخیره می شوند، اما ما از آن استفاده نمی کنیم. در عوض، همانطور که در خطوط پر رنگ شده مشاهده می کنید، از آبجکت Input  (که از ویژگی  app-&gt;input فراخوانی می شود) که در جوملا تعریف شده است برای بازیابی این مقادیر استفاده می کنیم. به این دلیل است که کلاس Input  تمیز کردن و فیلتر اضافی را فراهم میکند. در این متد ها می بینید که ما پارامترlast  را نیز درج می کنیم که در این حالت مقادیر را به صورت اعداد صحیح بدون علامت، فیلتر می کند.

برای متغیر $search ، می توانید ببینید که ما از روش دیگری استفاده می کنیم، getUserStateFromRequest  که وضعیت فعلی متغیر را با مقدار ارسال شده در فرم ترکیب می کند. این روش یک فیلتر را نیز می پذیرد. حالا متن زیر را پیدا کنیم و با متن پایینتر جایگزین کنید.

متن فعلی:

 
$search = $this->getUserStateFromRequest( 
$this->context . '.filter.search', 
'filter_search'); 
آن را با این جایگزین کنید:
 
$search = $this->getUserStateFromRequest( 
$this->context . '.filter.search', 
'filter_search', 
'string'); 

با این کار یک رشته پاکسازی شده و کاملاً رمزگشایی شده در جستجوی ذخیره شده بر می گردد تا بتوانیم از آن در سایت خود استفاده کنیم.

اینها فیلترهایی هستند که می توانیم استفاده کنیم:

  • int این عدد صحیح یا آرایه ای از اعداد صحیح را بر می گرداند.
  •  uintیک عدد صحیح بدون علامت یا آرایه ای از آنها را بر می گرداند.
  •  floatاین عدد، یک عدد ممیز شناور (یا آرایه ای از اعداد ممیز شناور) را بر می گرداند.
  •  booleanاین مقدار درست یا نادرست را بر می گرداند.
  • word یک رشته حاوی کاراکترهای A تاZ  یا زیر خط ( _ ) را بر می گرداند. هیچ نماد دیگری پذیرفته نمی شود. به حروف کوچک و بزرگ حساس نیست.
  •  alnumاین فیلتر یک رشته با کاراکترهای  Aتا  Z و فقط از  0 تا  9 را بر می گرداند. هیچ نمادی پذیرفته نمی شود. به حروف بزرگ و کوچک حساس نیست.
  • cmd این فیلتر یک رشته با کاراکتر برمی گردانداز A تا Z و از 0 تا 9 ، زیرخط ( _ )، نقطه (. )، و خط فاصله ( - ). به حروف کوچک و بزرگ حساس نیست.
  •  base64این فیلتر یک رشته با کاراکترهای  Aتا Z  و از 0 تا 9 ، اسلش های جلو ( / ) و فقط علامت های  + یا  = بر می گرداند. هیچ نماد دیگری پذیرفته نمی شود. به حروف بزرگ و کوچک حساس نیست.
  • string یا  htmlاین فیلتر (شما می توانید از هر یک از کلمات استفاده کنید) یک رشته معمولی را بر می گرداند و تگ های خطرناک HTML مانند script ،  apple و سایر برچسب های مورد استفاده در حملات را حذف می کند.
  • array این یک آرایه را بر می گرداند.
  •  pathاین یک مسیر فایل سیستم تمیز را بر می گرداند. وجود مسیر را بررسی نمی کند.
  •  trimاین رشته را بدون فاصله سفید ابتدایی یا انتهایی بر می گرداند.
  • raw این فیلتر هیچ کاری نمی کند، بنابراین فقط مقدار را همانطور که هست بر می گرداند.

همانطور که می بینید، فیلترهای زیادی وجود دارد که می توانیم از آنها برای پاکسازی اطلاعاتی که از فرم های خود دریافت می کنیم برای امنیت ورودی های خود استفاده کنیم. همچنین در صورت عدم استفاده از فیلتر، نام فیلتر را با غلط املایی می نویسیم یا از فیلتری استفاده می کنید که در این لیست وجود ندارد، جوملا به طور پیش فرض، فیلتر cmd  را اعمال می کند.

فیلتر کردن داده های ورودی قبل از ذخیره آنها در پایگاه داده

در بخش قبل، دیدیم که چگونه می توانیم داده های ورودی را هنگام بازیابی مستقیم از درخواست فیلتر کنیم. اما وقتی از کلاس های جوملا MVC در فصل 2 استفاده کردیم، نیازی به بازیابی داده ها مستقیماً از درخواست نداشتیم: این یک جادوی جوملا  MVC بود.

در فصل 2 ، ما یاد گرفتیم که چگونه یک نمای ویرایشی برای کامپوننت خود ایجاد کنیم. در مورد ما، ما مجبور نبودیم با متدهای  (save) یا (apply) کار کنیم، زیرا در حال گسترش FormController  جوملا بودیم که با آنها سروکار داشت. در داخل، کنترلر از متد validate در کلاس  FormModel استفاده می کند، که داده ها را با استفاده از فیلترهای فرم که در تعریف فرم پیکربندی شده اند، فیلتر و اعتبارسنجی می کند، همانطور که در فصل 4دیدیم.

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

بنابراین، به عنوان مثال، هنگام ذخیره فاکتورها، ما فرم فاکتور خود را مانند این شکل قرار می دهیم:

src/component/admin/forms/invoice.xml 

 
<?xml version="1.0" encoding="UTF-8"?> 
<form addrulepath="administrator/components/com_spm/rules"> 
<field 
name="number" 
type="text" 
label="COM_SPM_INVOICE_NUMBER" 
/> 
<field 
name="amount" 
type="text" 
label="COM_SPM_INVOICE_AMOUNT" 
inputmode="decimal" 
class="validate-notzero" 
required="true" 
pattern="[0-9]{1,}(\.[0-9]{1,2})?" 
/> 
<field 
name="items" 
type="text" 
label="COM_SPM_INVOICE_ITEMS" 
/> 
<field 
name="customer" 
type="text" 
label="COM_SPM_INVOICE_CUSTOMER" 
/> 
</form> 

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

بنابراین، بیایید چند فیلتر اضافه کنیم تا به شکل زیر درآید:

 
<?xml version="1.0" encoding="UTF-8"?> 
<form addrulepath="administrator/components/com_spm/rules"> 
<field 
name="number" 
type="text" 
label="COM_SPM_INVOICE_NUMBER" 
filter="alnum" 
/> 
<field 
name="amount" 
type="text" 
label="COM_SPM_INVOICE_AMOUNT" 
inputmode="decimal" 
class="validate-notzero" 
required="true" 
pattern="[0-9]{1,}(\.[0-9]{1,2})?" 
filter="float" 
/> 
<field 
name="items" 
type="text" 
label="COM_SPM_INVOICE_ITEMS" 
/> 
<field 
name="customer" 
type="text" 
label="COM_SPM_INVOICE_CUSTOMER" 
filter="int" 
/> 
</form> 

ویژگی فیلتر (filter) جدید در اینجا برجسته شده است. این فیلتر خاص را قبل از بازیابی آن از درخواست روی فیلد اعمال می کند، بنابراین می توانید مطمئن شوید که نوع دقیق داده  ای را که انتظار دارید، مدیریت می کنید.

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

جلوگیری از حملات جعل درخواست بین سایتی (CSRF) در فرم ها

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

در جوملا، ما راهی برای جلوگیری از این حمله داریم: با قرار دادن یک رشته تصادفی به نام Token  در داده های فرم، این رشته پس از دریافت درخواست، در ابتدای کنترلر بررسی می شود.

در فصل 3 ، زمانی که ما یک فرم ویرایش برای پروژه های خود اضافه کردیم، این token را اضافه کردیم. بنابراین، اگر به فایل src/component/admin/tmpl/project/edit.php  نگاهی بیندازید ، در پایان، کد زیر را مشاهده خواهید کرد:

 
use Joomla\CMS\HTML\HTMLHelper; 
... 
<?php echo HTMLHelper::_('form.token'); ?> 
</form> 

در اینجا ابتدا کلاس HTMLHelper  را اعلام می کنیم و سپس از آن برای چاپ توکن فرم خود استفاده می کنیم. این متد تمام فیلد HTML ورودی را، خروجی می دهد:

 
<input type="hidden" name="AAABBBCCCDDDEEE" value="1"> 

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

هنگامی که فرم ارسال شد، اولین چیزی که در روش مدیریت داده ها انجام می شود، متد بررسی می شود. در مورد ما، ما FormController جوملا را گسترش می دادیم ، بنابراین باید فایل داخل بسته ی نصبی جوملا libraries/src/MVC/Controller/FormController.php را بررسی کنیم.

در ابتدای متد  save را با کد زیر خواهیم دید:

 
public function save($key = null, $urlVar = null) 
{ 
// Check for request forgeries. 
$this->checkToken(); 
... 
} 

این به طور خودکار توکن را بررسی می کند.

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

جلوگیری از حملات اسکریپتی بین سایتی  (XSS)

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

لینک

https://hackedsite.com?value=<script>/*+Bad+stuff+here...+*/</script>

باشد که کد زیر را اجرا می کند:

 
<?php echo $_REQUEST('value');?> 

در جوملا، کاهش این حمله واقعاً آسان است فقط باید از متد $app->input->get()  که در ابتدای این فصل دیدیم برای بازیابی مقادیر با فیلترهای HTML یا رشته  ای (string) استفاده کنیم.

همچنین، پیاده سازی توکن CSRF که در بخش قبل دیدیم، از ما در برابر این حمله محافظت می کند، زیرا مهاجم نمی تواند توکن مناسب برای دور زدن امنیت ما ایجاد کند.

جلوگیری از تزریق SQL

تا اینجای کار، ما برنامه وب خود را با استفاده از فیلترها و توکن CSRF ایمن کرده ایم. از آنجایی که ما از کلاس های جوملا MVC استفاده می کنیم، که با تمیز کردن زیادی سروکار دارند، اکنون کاملاً ایمن هستیم.

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

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

$userid = $_POST['userid']; 
$query = "SELECT * FROM users_table WHERE userid = $userid"; 

همانطور که می بینید، هیچ فیلتری برای دریافت مقدار  $userid به طور مستقیم از  $_POST جهانی وجود ندارد، بنابراین یک کاربر مخرب می تواند  "1; DROP TABLE users_table;" را ارسال کند. رشته هنگامی که کوئری ایجاد می شود، نتیجه به صورت زیر خواهد بود:

 
$query = "SELECT * FROM users_table WHERE userid = 1; DROP TABLE users_table;"  

هنگام اجرای این کوئری،  users_table شما حذف خواهد شد.

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

در جوملا، هنگام استفاده از کلاس  DatabaseQuery (که ما از کل این کتاب برای تعامل با پایگاه داده استفاده می کنیم)، خطر ابتلا به چنین حمله ای کم است، به خصوص که ما تمام داده هایی را که از کاربر دریافت می کنیم، فیلتر می کنیم.

در هر صورت، ریسک کم، بیشتر از صفر است، بنابراین یکی از پیشرفت های بزرگی که با انتشار جوملا 4 به وجود آمد، اضافه شدن دستورات آماده شده با SQL  است. این ویژگی کارایی پرس و جو های پایگاه داده شما را بهبود می بخشد (مخصوصاً اگر تکراری باشند) و عملاً احتمال تحت تأثیر قرار گرفتن توسط یک حمله تزریق SQL را از بین می برد. تنها نقطه ضعف دستورات آماده این است که اشکال زدایی جملات SQL را کمی دشوار تر  میکند، زیرا $query-&gt;dump(); ، که برای نمایش محتوای پرس و جو پایگاه داده استفاده می شود، دیگر کار نمی کند.

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

بیایید به مدل پروژه frontend خود برگردیم و روی متد getItem در فایل src/component/site/src/Model/Project.php  تمرکز کنیم:

 
function getItem($pk = null) 
{ 
$id = (int) $pk ?: (int) $this->getState('project.id'); 
if (!$id) { 
throw new \Exception('Missing project id', 404); 
} 
if ($this->_item !== null && $this->_item->id != $id) { 
return $this->_item; 
} 
$db = $this->getDatabase(); 
$query = $db->getQuery(true); 
$query->select('*') 
->from($db->quoteName('#__spm_projects', 'a')) 
->where('a.id = ' . (int) $id); 
$db->setQuery($query); 
$item = $db->loadObject(); 
if (!empty($item)) { 
$this->_item = $item; 
} 
return $this->_item; 
} 

در کد پر رنگ شده، می توانیم یک کوئری SQL را ببینیم که می تواند از عبارات آماده شده بهره مند شود. می توانیم آن را با این کد جایگزین کنیم:

 
$query->select('*') 
->from($db->quoteName('#__spm_projects', 'a')) 
->where('a.id = :userid'); 
$query->bind(':userid', (int) $id); 

همانطور که می بینید، مشکل بزرگی نیست - ما فقط باید جایگزینی مستقیم مقدار را با یک عبارت ( :userid ) تغییر دهیم، و سپس باید عبارت را با مقدار مناسب ( $id ) مرتبط کنیم. ما حتی می توانیم تایپ کست (typecasting[1]) را حفظ کنیم و مطمئن باشیم که فقط یک عدد صحیح تزریق می کنیم.

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

دارایی های خود را برای آینده تضمین کنید

در فصل 3، ما دارایی های وب را با استفاده از مدیریت دارایی وب جوملا به کامپوننت خود اضافه کردیم و متوجه تمام مزایای آن شدیم. اما در برخی مواقع، زمانی که می خواهید تغییرات کوچک و سریعی در کد خود ایجاد کنید، ممکن است وسوسه شوید که استایل ها یا جاوا اسکریپت خود را مستقیماً در کد فایل های پیکربندی HTML خود قرار دهید. حتی بیشتر، ممکن است کمی احساس تنبلی کنید و آنها را به جای پوشه رسانه در پوشه افزونه خود قرار دهید.

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

از زمان انتشار جوملا 5 ، کاربران می توانند فایل های جوملای خود را خارج از پوشه عمومی سرور نصب کنند. در این موارد ممکن است لینک به URL مستقیم فایل ها غیرممکن باشد.

امروزه افزودن ویژگی های HTML مانند onclick=""  یا onchange="" منسوخ شده است و باید از آنها اجتناب کنید. در عوض، رویدادهای خود را در فایل های جاوا اسکریپت خود تعریف کنید.

برای جلوگیری از مشکلات، باید این قوانین را دنبال کنید:

  • از مدیریت دارایی های وب جوملا یا HTMLHelper ، برای بارگذاری استایل ها و اسکریپت های خود استفاده کنید. (همانطور که در فصل 3 دیدیم)
  • کد جاوا اسکریپت یا رویدادها را در کد HTML خود وارد نکنید
  • فونت ها، تصاویر، اسکریپت ها و استایل های خود را در مسیر مناسب پوشه رسانه ذخیره کنید

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

سخت شدن دسترسی به فایل های شما

جوملا یک CMS با یک چهارچوب قدرتمند است و توسعه افزونه ها برای جوملا به لطف همه کدهای ارائه شده توسط همه ی داوطلبان، سرگرم کننده و آسان است. اما نباید فراموش کنیم که برنامه وب ما در جوملا، مجموعه ای از فایل های PHP است که به طور کلی با هم کار می کنند.

جوملا معمولاً روی یک وب سرور (معمولاًApache  یا Nginx ) اجرا می شود که می تواند کد PHP را اجرا کند. اگر یک فایلphp سفارشی با مقداری کد معتبر در وب سایت جوملا خود آپلود کنید و سعی کنید به آن دسترسی داشته باشید، خواهید دید که بدون مشکل کار می کند.

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

در جوملا، رایج ترین متد برای انجام این کار، افزودن عبارت زیر در ابتدای فایل های ما است:

 
defined('_JEXEC') or die; 

وقتی سعی می کنید به هر فایلی با این عبارت دسترسی پیدا کنید، وب سرور بررسی می کند که آیا ثابت  _JEXEC تعریف شده است یا خیر. در غیر این صورت اجرا را متوقف می کند.

ثابت _JEXEC توسط جوملا در ابتدای چرخه اجرای آن تعریف شده است تا تضمین کند که فایل های PHP ما فقط در جوملا استفاده خواهند شد.

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

با استفاده از افزونه  JED Checker

در فصل بعدی، خواهیم دید که چه چیزی مستلزم توزیع افزونه ما است، اما ذکر افزونه  JED Checker در اینجا ارزشمند است.

 JED Checker یک افزونه ی جوملا است که به طور خودکار، کد افزونه شما را برای مشکلاتی که مانع ارسال آن به فهرست افزونه های جوملا (Joomla Extensions Directory TM) می شود، بررسی میکند.

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

برای استفاده JED Checker، این مراحل را دنبال کنید:

  1. ابتدا باید آن را روی یک سایت جوملا نصب کنید (نیازی نیست که سایت تست شما باشد، هر سایت جوملا این کار را می کند). برای نصب آن، به backend  سایت بروید، روی System  کلیک کنید و در قسمت Install  روی  Extensions  کلیک کنید.
  2. اکنون در نصب کننده، روی زبانه Install from Web  کلیک کنید و در قسمت جستجو  JED Checker را تایپ کنید.  مطابق شکل 13.1 ، افزونه ی JED Checker را مشاهده خواهید کرد.
  3. پس از کلیک بر روی دکمه ذره بین،  JED Checker ظاهر می شود. روی نام افزونه و سپس بر روی دکمه Install  کلیک کنید.
  4. پس از نصب، به قسمت Components و JED Checker از منوی کناری بروید؛ فرم کوچکی را مشاهده خواهید کرد که در آن باید یک بسته ZIP که حاوی کد افزونه شما است را آپلود کنید.
  5. بسته را ایجاد کنید و روی Submit  کلیک کنید. پس از آپلود فایل بر روی دکمه  Check کلیک کنید. نتایج را برای افزونه خود خواهید دید.

همانطور که در شکل 13 نشان داده شده است ، در سمت چپ، نواحی مختلف بررسی شده اند و نشان کوچکی وجود دارد که تعداد و شدت مشکلات را با رنگ ها نشان می دهد:

شکل 13.1 - جستجوگر JED در تب Install from Web نصب کننده افزونه های جوملا نشان داده شده است.

همانطور که در شکل 13.2 نشان داده شده است، ما بر روی موضوعات زیر که در گزارش نشان داده شده است تمرکز خواهیم کرد :

  • فایل های PHP فاقد امنیت JEXEC هستند :

این بررسی به شما می  گوید که چه تعداد از فایل های شما تعریف شده ('_JEXEC')  یا die را در ابتدای آنها ندارند. این گزارش نباید هیچ فایلی را نشان دهد که تحت تأثیر این مشکل قرار گرفته است.

  •  Joomla FrameworkTM منسوخ و ناامن: این بررسی شما را از کد منسوخ یا نا ایمن در افزونه خود مطلع می کند. در حالت ایده آل، نباید کد منسوخ شده ای وجود داشته باشد. از سوی دیگر، کد ناامن باید اصلاح شود.
  • JAMSS - Joomla Anti-Malware Scan scripts  اسکریپت های اسکن ضد بدافزار جوملا: در این بخش، جستجوگر اسکریپتی را اجرا می کند که بدافزار را در فایل ها شناسایی می کند. اگر فایلی را در این بخش مشاهده کردید، به این معنی است که از فایل هایی استفاده می کنید که حاوی بدافزار هستند، بنابراین باید آنها را بررسی کرده و آنها را رفع یا حذف کنید. مطمئن شوید که یک افزونه ی امن دارید، این بخش نباید هیچ فایلی را گزارش کند:

شکل 13.2 - گزارش JED Checker برای کامپوننت ما قبل از اعمال اصلاحات امنیتی

منابع فصل

 

  • مقاله گسترده ای در مورد حملات CSRF در ویکی پدیا وجود دارد:

 https://en.wikipedia.org/wiki/Cross-site_request_forgery

  • می توانید با مراجعه به صفحه GitHub آن در JED Checker مشارکت کنید و اطلاعات بیشتری در مورد آن بیابید:

 https://github.com/joomla-extensions/jedchecker

 

 



[1] Type casting یک ویژگی در تایپ اسکریپت است که به توسعه ‌دهندگان اجازه می‌دهد به صراحت تایپ یک مقدار را از یک نوع به نوع دیگر تغییر دهند. استفاده از ویژگی type casting مخصوصاً زمانی که با داده‌های داینامیک کار می‌کنیم یا زمانی که تایپ یک مقدار به ‌طور خودکار به درستی استنتاج نمی ‌شود، بسیار مفید می ‌باشد.

فصل های دیگر کتاب

نوشتن دیدگاه

ارسال