تامین امنیت در وردپرس

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

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

مجوز دسترسی کاربر

شاید قبلا با این مسئله رو به رو شده باشید که هنگام دسترسی به صفحه ای در مدیریت وردپرس به دلیل نداشتن سطح دسترسی لازم با خطا مواجه شدید. برای ایجاد محدودیت در دسترسی کاربر به بخش های مختلف می توانید از تابع current_user_can استفاده نمایید. این تابع امکان دسترسی یا انجام عمل معینی توسط کاربر فعلی را بررسی می کند. در صورت تایید امکان دسترسی مقدار true و در غیر این صورت مقدار false برگردانده می شود. این تابع دو پارامتر ورودی می پذیرد که پارامتر دوم اختیاری است. پارامتر اول یک قابلیت معین (مانند ویرایش پست) یا یک نقش تعریف شده (مانند مدیر یا ویرایشگر) باید باشد. پارامتر دوم آیدی شی است که امکان دسترسی به آن توسط کاربر فعلی باید بررسی شود.

مثال:

< ?php
        
// Capability:
if ( !current_user_can('install_plugins') )
    wp_die( 'Insufficient permissions' );
        
// Role:
if( !current_user_can('editor') )
    wp_die( 'You cannot edit this setting' );
? >   

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

متغیر nonce

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

در وردپرس توابعی برای ایجاد nonce برای لینک ها و فرم ها و همچنین بررسی و تایید صحت nonce ارسالی، تعریف شده است.

برای ایجاد متغیر nonce در لینک ها می توان از تابع wp_nonce_url استفاده کرد. این تابع سه پارامتر ورودی می پذیرد که تنها اولین پارامتر آن اجباری است. پارامتر اول لینک مورد نظر، پارامتر دوم عنوان عملی که برای آن nonce (اکشن nonce) ایجاد می شود و پارامتر سوم نام nonce است. خروجی این تابع لینک ورودی به اضافه پارامتر nonce است که برای عمل مورد نظر (مانند حذف پست) ایجاد شده است. مثال: حذف پست با آیدی خاص

برای ایجاد متغیر nonce در لینک ها می توان از تابع wp_nonce_url استفاده کرد. این تابع سه پارامتر ورودی می پذیرد که تنها اولین پارامتر آن اجباری است. پارامتر اول لینک مورد نظر، پارامتر دوم عنوان عملی که برای آن nonce (اکشن nonce) ایجاد می شود و پارامتر سوم نام nonce است. خروجی این تابع لینک ورودی به اضافه پارامتر nonce است که برای عمل مورد نظر (مانند حذف پست) ایجاد شده است.

مثال: حذف پست با آیدی خاص

< ?php
        
$delete_url = add_query_arg( array('bmpt_action'= > 'delete','id'= > $id) );
$nonced_url = wp_nonce_url( $delete_url, 'bmpt_utags-delete_tag'.$id );
? > 
 < a href=" < ?php echo $nonced_url; ? > " > delete < /a >  this tag

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

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

مثال:

< form action="" method="post" > 
     < ?php wp_nonce_field( 'bmpt_utags-rename_tag' ); ? > 
  
     
     < input type="text" name="name" value=" < ?php echo esc_attr($name); ? > " / > 
     < input type="submit" value="Rename" / > 
 < /form >  

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

مثال:

<?php
$nonce = wp_create_nonce( 'my-nonce' );
?>
<a href='myplugin.php?do_something=some_action&amp;_wpnonce=<?php echo $nonce; ?>'>Do some action</a>

پس از ایجاد nonce  برای کنترل صحت دسترسی و تایید nonce ارسالی می توان از توابع check_admin_referer و wp_verify_nonce استفاده نمود. تابع check_admin_referer برای کنترل اعتبار nonce ارسالی از صفحه ای در مدیریت وردپرس استفاده می شود اما از تابع wp_verify_nonce برای تایید  اعتبار nonce به صورت کلی می توان استفاده نمود.

تابع check_admin_referer دو پارامتر ورودی می پذیرد: پارامتر اول اکشن nonce و پارامتر دوم نام nonce که هر دو پارامتر اختیاری هستند.

مثال: استفاده از nonce برای فرمی در تنظیمات پلاگین

<form method="post">
   <!-- some inputs here ... -->
   <?php wp_nonce_field( 'name_of_my_action','name_of_nonce_field' ); ?>
</form>

کنترل nonce در صفحه ای که فرم به آن ارسال می شود:

<?php
// if this fails, check_admin_referer() will automatically print a "failed" page and die.
if ( ! empty( $_POST ) &amp;&amp; check_admin_referer( 'name_of_my_action', 'name_of_nonce_field' ) ) {
   // process form data, e.g. update fields
}

تابع wp_verify_nonce نیز دو پارامتر ورودی می پذیرد: پارامتر اول عنوان متغیر nonce ارسالی و پارامتر دوم اکشن nonce.

مثال:

<?php
// Step A: Create an nonce, and add it as a query var in a link to perform an action.
$nonce = wp_create_nonce( 'my-nonce' );
echo "<a href='myplugin.php?_wpnonce={$nonce}'>" . __( 'Save Something', 'textdomain' ) . "</a>";

کنترل nonce ارسالی:

<?php 
$nonce = $_REQUEST['_wpnonce'];
if ( ! wp_verify_nonce( $nonce, 'my-nonce' ) ) {
    die( __( 'Security check', 'textdomain' ) ); 
} else {
    // Do stuff here.
}
?>

اعتبارسنجی و تصفیه داده

اعداد صحیح

برای اعتبارسنجی و تصفیه اعداد صحیح می توانید از توابع is_int و intval استفاده نمایید. همچنین در مورد اعداد صحیح مثبت می توانید از تابع absint وردپرس استفاده کنید. این تابع مقدار ورودی تابع را به صورت یک عدد صحیح مثبت بر می گرداند. برای حالتی که طول اعداد از ماکزیمم طول تعریف شده برای داده های integer بیشتر باشد، می توانید از تابع ctype_digit برای اعتبارسنجی اعداد استفاده کنید.

< ?php
$num = '100000000000000000';
        
// Validate large integers
return( ctype_digit( $num ) );
? >

رشته های الفبایی

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

<?php
// Validate alphabetic strings
return( ctype_alpha( $num ) );
?>   

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

<?php
// Validate alphanumeric strings
return( ctype_alnum( $num ) );
?>    

توابع ctype توانایی تشخیص کاراکترهای فارسی را ندارند. یکی از روش های متداول برای اعتبارسنجی کاراکترهای فارسی استفاده از تابع preg_match است.

function validate_name($str)
{
    if(!preg_match("/^[\x{600}-\x{6FF} A-Za-z]+$/u",$str))
    return false;
    else
    return true;
}

تابع بالا امکان اعتبارسنجی کاراکترهای الفبایی فارسی و انگلیسی را فراهم می آورد.

نکته: به طور کلی برای اعتبارسنجی داده های مختلف می توانید از تابع preg_match و یا توابع فیلتر php استفاده نمایید.

تصفیه رشته از کاراکترهای نامطلوب

تابع sanitize_text_field برای تصفیه عمومی مقادیر متنی ارسالی استفاده می شود. این تابع کاراکترهای نامعتبر UTF8، تگ های HTML، شکستگی خطوط و فاصله های اضافی را از رشته ورودی حذف می کند و رشته تصفیه شده را بر می گرداند.

<?php
        
var_dump( sanitize_text_field( "I am nice.\n Very  < em > nice < /em > !  " ) );
        
// result:
// string(21) "I am nice. Very nice!"
        
?>  

در حالتی که بخواهید تنها تگ های HTML را از ورودی حذف کنیم و سایر موارد را نگه دارید می توانید از تابع wp_stip_all_tags استفاده نمایید.

اعتبارسنجی و تصفیه آدرس ایمیل

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

<?php
        
var_dump( sanitize_email( 'ozh@ozh' ) );
// string(0) ""
        
var_dump( sanitize_email( 'ozh@ozh..org' ) );
// string(0) ""
        
var_dump( sanitize_email( '(ozh)@(ozh).org' ) );
// string(11) "ozh@ozh.org"
        
var_dump( sanitize_email( 'ozh@ozh.org' ) );
// string(11) "ozh@ozh.org"
?>  

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

تگ های HTML

یکی از توابعی که برای تصفیه و معتبرسازی کدهای HTML می تواند مورد استفاده قرار گیرد تابع force_balance_tags است. این تابع اشکالات مربوط به ساختار تگ ها در تکه کد مورد نظر را برطرف می کند.

<?php
        
// 1. Fixing missing closing tags:
        
$html = ' < p > Please close my  < strong > tags!';
var_dump( force_balance_tags( $html ) );
// string(45) " < p > Please close my  < strong > tags! < /strong >  < /p > "
        
// 2. Fixing incorrectly nested tags:        
$html = ' < p > Please  < strong >  < em > fix < /strong >  < /em >  nesting! < /p > ';
var_dump( force_balance_tags( $html ) );
// string(52) " < p > Please  < strong >  < em > fix < /em >  < /strong >  nesting! < /p > "       
?> 

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

<?php
        
$allowed = array(
    'strong' = >  array(),
    'a'      = >  array(
        'href'  = >  array(),
        'title' = >  array()
    )
);
$html = ' < a href="#" class="external" > site < /a > 
          <b>bold?</b>     < strong > bold! < /strong > ';
        
var_dump( wp_kses( $html, $allowed ) );
// string(58) " < a href="#" > site < /a >  bold?  < strong > bold! < /strong > "
?>

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

مثال:

< h1 >  <?php echo esc_html( $page_title; ) ?>  < /h1 > 
  a href="#anchor" title=" <?php echo esc_attr( $link_title; ) ?> "  > link < /a >   
<img src="/images/duck.png" 
alt="<?php echo esc_attr( $alt_text ); ?>" 
title="<?php echo esc_attr( $title ); ?>" >

آدرس لینک ها

تابع esc_url تابعی است که برای تصفیه آدرس لینک ها در وردپرس به کار می رود. این تابع باعث ترجمه کاراکترهای مجاز در آدرس به موجودیت های HTML می شود. برای تصفیه آدرس ها بدون ترجمه کاراکترهای مجاز می توانید از تابع esc_url_raw استفاده نمایید

<?php
        
$url = "http://ex[a]mple.com/?q=1 &amp; s=2'";
        
var_dump( esc_url( $url ) );
// string(38) “http://example.com/?q=1 &amp; #038;s=2 &amp; #039;"
        
var_dump( esc_url_raw( $url ) );
// string(28) "http://example.com/?q=1 &amp; s=2'"
?>   

تغییر مسیر امن

استفاده از تابع header برای ایجاد تغییر مسیر و هدایت کاربر به صفحه ای خاص می تواند یکی از موارد آسیب پذیری در یک پلاگین باشد. برای تغییر مسیر درست در وردپرس بهتر است از تابع wp_redirect استفاده نمایید. این تابع سه پارامتر ورودی می پذیرد که تنها پارامتر اول آن اجباری است. پارامتر اول مسیر مورد نظر برای هدایت کاربر، پارامتر دوم کد وضعیت پاسخ HTTP و پارامتر سوم عنوان درخواست کننده تغییر مسیر (مثلا WordPress).

معمولا برای پایان دادن به فرآیند هدایت صفحه، بعد از تغییر مسیر باید از تابع exit یا die استفاده نمایید.

<?php
 wp_redirect( home_url() ); 
exit; 
?>

تصفیه کد جاوا اسکریپت

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

<?php 
$message = get_post_meta( get_the_ID(), 'onclick_message', true ); 
?>
<a href="/blog/" onclick="alert('<?php echo esc_js( $message ); ?>')">...</a>

پست های مرتبط

Leave a Comment