امنیت وردپرس: نانس(Nonce) دیواری محکم در مقابل حملات CSRF

حدود پانزده سال از معرفی و ارائه وردپرس(در سال ۲۰۰۳) گذشته است و در این مدت بسیاری از باگ ها و حفره های امنیتی آن رفع و رجوع شده است، اما باز هم با قطعیت نمی توان گفت که وردپرس فاقد هر گونه مشکل امنیتی است، دلیل آن هم وجود افزونه ها و قالب هایی است که استانداردها و نکات امنیتی لازم را پیاده سازی نکرده اند. در حقیقت وردپرس خود مشکل نیست بلکه مواردی است که به آن اضافه می کنیم.

ضرب المثل معروفی است که می گوید: “علاج واقعه قبل از وقوع باید کرد”. بنابراین بهترین کاری که برای مقابله با طیف وسیعی از باگ های امنیتی می توانید انجام دهید استفاده از Nonce است، اگر توسعه دهنده قالب یا پلاگین هستید پیشنهاد می کنیم این مقاله را تا انتها مطالعه فرمائید.

نانس چیست؟

نانس نشانه ای(Token) منحصربفرد و موقت از مجموعه ای از حروف و اعداد می باشد، این رشته یکبارمصرف(Number Used Once) به صورت خودکار در سمت سرور ایجاد و به کلاینت ارسال می گردد، سپس در صورت انجام عملیاتی مثل افزودن، حذف یا ویرایش این نشانه امنیتی به سرور ارسال خواهد شد تا وردپرس مطمئن شود که درخواست ارسالی جعلی نیست. عملا با اینکار اعتبار و اطمینان داده ها تضمین خواهد شد و فرد دیگری نمی تواند به جای یک کاربر واقعی درخواست های مخرب خود را برای سرور ارسال کند.

همانطور که در تصویر زیر مشاهده می کنید وردپرس در هنگام حذف یک پست رشته نانس را به انتهای آدرس اضافه می کند.

nonce در وردپرس

 

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

اعتبار nonce در وردپرس

 

Nonce به طور گسترده در کلیه بخش های وردپرس از جمله حذف برچسب(Tag)، ویرایش دسته(Category) و… استفاده می شود.

چرا باید از Nonce استفاده کنیم؟

نانس به شما کمک می کند تا از وب سایت تان در برابر حمله جعل درخواست (Cross Site Request Forgery – به اختصار CSRF یا XSRF) محافظت کنید. در حمله CSRF فرد مهاجم سعی می کند با استفاده از تکنیک های مهندسی اجتماعی فرد قربانی رو ترغیب کند تا وارد سایت او شود. برای انجام اینکار هم از روش های مختلفی مثل ارسال لینک صفحه وب از طریق ایمیل(با محتوای جذاب و وسوسه انگیز) برای طعمه خود استفاده می کند.

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

به CSRF حمله یکبار کلیک(One Click Attack) نیز گفته می شود.

در سناریویی دیگر فرض کنید برای صفحه تماس با ما از افزونه فرضی Contact Us XYZ استفاده کرده اید و توسعه دهنده آن مکانیزم ها لازم برای مقابله با حملات CSRF را در نظر نگرفته است. در اولین گام فرد مهاجم یک صفحه وب ساده در سایت خود قرار می دهد که مقادیر فرم تماس با ما را با استفاده از متد Post ارسال می کند، سپس لینک صفحه مربوطه را در فروم های(Forum) معروف ارسال کرده و از افراد می خواهد که بر روی لینک او کلیک کنند، به همین راحتی پس از مدت زمان کوتاهی دیتابیس وردپرس با اطلاعات فیک پر شده و عملا وب سایت موردنظر Down خواهد شد.

مثال های بررسی شده موارد ساده ای از اهداف CSRF بودند، اگر کلیه درخواست های ارسالی به سرور در برابر این نوع حمله ایمن شده باشند درخواست های جعلی با شکست مواجه خواهند شد، چرا که فرد مهاجم از ساختار و مکانیزم تولید نانس هیچگونه اطلاعی ندارد.

نانس چگونه تولید می شود؟

فرآیند ایجاد Nonce بدین صورت است:

  1. سرور پس از تولید Nonce آن را در حافظه محلی خود ذخیره کرده و برای کلاینت ارسال می کند.
  2. کلاینت نانس را در درخواست های مدنظر خود قرار می دهد.
  3. در صورتی که سرور درخواستی را دریافت کند ابتدا از وجود نانس مطمئن می شود، سپس نانس ارسالی را با نانس ذخیره شده در حافظه محلی خود مقایسه می کند، اگر اعتبار آن تایید شود درخواست را انجام می دهد در غیر اینصورت ریجکت خواهد شد.
  4. پس از اجرای درخواست نانس نامعتبر خواهد بود و از بین می رود(Destroy می شود چرا که یکبار مصرف است).

اگر Nonce به درستی پیاده سازی شده باشد CSRF دیگر مشکل ساز نخواهد بود، به این نکته توجه داشته باشید که فرد مهاجم به هیچ عنوان نمی تواند شناسه جعلی(Fake) تولید کرده و به سرور هدف ارسال کند، چرا که وردپرس برای تولید و اعتبارسنجی نانس از دو پارامتر NONCE_KEY و NONCE_SALT موجود در فایل wp-config.php استفاده می کند.

کلید نانس در wp-config

 

همچنین نانس حداکثر ۲۴ ساعت معتبر خواهد بود و اگر در این بازه زمانی استفاده نشود از درجه اعتبار ساقط شده و ارزشی نخواهد داشت، همچنین در صورت Logout کاربر و اتمام نشست، کلیه نانس های تولید شده از بین می روند.

چگونه Nonce را عملیاتی کنیم؟

به منظور پیاده سازی نانس باید دو مرحله زیر را انجام دهید:

  1. مرحله ایجاد(Creation)
  2. مرحله اعتبارسنجی(Verification)

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

  1. قرار دادن نانس در URL(به صورت Query String) با wp_nonce_url
  2. افزودن به فرم های وب به کمک wp_nonce_field
  3. استفاده از wp_create_nonce

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

  1. تابع wp_verify_nonce
  2. تابع check_admin_referer
  3. اعتبارسنجی درخواست های ایجکس(Ajax) با تابع check_ajax_referer

در ادامه هر کدام از موارد بالا را با جزئیات بیشتری بررسی می کنیم.

۱- ایجاد Nonce

۱-۱- wp_nonce_url

این تابع در مواقعی استفاده می شود که می خواهید عملیاتی را از طریق URL انجام دهید، مشابه مثالی که در ابتدای این آموزش بررسی کردیم، نحوه استفاده از آن بدین صورت می باشد:

wp_nonce_url( string $actionurlint|string $action = string $name = ‘_wpnonce’ )

  1. پارامتر اول آدرسی است که نانس باید به آن اضافه شود(اجباری).
  2. دومین پارامتر نامی است که عملیات موردنظر را توصیف کرده و در هنگام اعتبارسنجی نانس استفاده می شود(اختیاری).
  3. توسط این پارامتر می توانید نام نانس را تغییر داده و مثلا به جای آن از کلمه Token استفاده کنید، مقدار پیش فرض wpnonce_ می باشد(اختیاری).

برای درک بهتر موضوع کار با یک مثال ادامه می دهیم:

$admin_url = admin_url( 'post.php?action=delete' );
$add_args_url = add_query_arg( 'post_id', 10, $admin_url );
$nonce_url = wp_nonce_url( $add_args_url, 'delete_my_post', 'token' );
echo '<a href="' . $nonce_url . '">Delete Post</a>';

 

خروجی نهایی بدین صورت ایجاد می شود:

<a href="http://localhost/tuts/wp-admin/post.php?action=delete&post_id=10&token=731c5ad84a">Delete Post</a>

wp_nonce_field -2-1

این تابع به صورت پیش فرض دو فیلد Input مخفی(Hidden) به فرم های HTML اضافه می کند، یک فیلد برای نگهداری نانس و دیگری برای آدرس ارجاع دهنده، نحوه فراخوانی آن اینگونه است:

wp_nonce_field( int|string $action = string $name = “_wpnonce”bool $referer = truebool $echo = true )

  1. اولین پارامتر نامی است که عملیات موردنظر را توصیف کرده و در زمان اعتبارسنجی نانس استفاده خواهد شد(اختیاری).
  2. این پارامتر برای تغییر نام نانس است(اختیاری).
  3. اگر مقدار پارامتر سوم false باشد فیلد hidden ارجاع دهنده تولید نخواهد شد(اختیاری).
  4. اگر مقدار این پارامتر false باشد هیچکدام از فیلدها در خروجی نشان داده نمی شوند(اختیاری).

پارامترهای تابع wp_nonce_field اختیاری بوده و نیازی به مقداردهی آنها نیست، اما بهتر است به منظور تامین امنیت بیشتر دو پارامتر ابتدایی را حتما مشخص کنید.

کار را با یک مثال ادامه می دهیم:

<form method="post" action="">
   <?php wp_nonce_field( 'my_secure_form', 'st_token' ); ?>
   <input type="submit" value="ارسال">
</form>

 

فرم HTML موردنظر نیز به صورت زیر تولید خواهد شد:

<form method="post" action="">
   <input type="hidden" id="st_token" name="st_token" value="3ee4ada504">
   <input type="hidden" name="_wp_http_referer" value="startuptuts.com/">
   <input type="submit" value="ارسال">
</form>

 

حال می توانید st_name را در سمت سرور به کمک متغیرهای سراسری GET، $_POST_$ و REQUEST_$ دریافت کرده و اعتبارسنجی کنید، همچنین مقدار فیلد wp_http_referer_ با [‘SERVER[‘REQUEST_URI_$ قابل دسترسی است.

wp_create_nonce -3-1

با تابع wp_create_nonce می توانید در هر جایی(URL، فرم های وب) نانس تولید کنید، این تابع فقط یک پارامتر دارد:

wp_create_nonce( string|int $action =  )

  1. عملیات موردنظر را توصیف کرده و در هنگام اعتبارسنجی کاربرد دارد(اختیاری).
$my_nonce = wp_create_nonce('edit_record');
<form method="post" action="">
   <input type="hidden" id="nonce_form" name="nonce_form" value="<?php echo $my_nonce ?>">
   <input type="submit" value="ارسال">
</form>

۲- اعتبارسنجی Nonce

مهمترین کاری که پس از ایجاد ناس باید انجام دهیم اعتبارسنجی مقادیری است که کاربران از طریق لینک ها(URL) و یا فرم های وب(Submit Forms) ارسال می کنند.

۱-۲- wp_verify_nonce

به کمک این تابع می توانید نانس های که از طریق URL یا فرم های وب ارسال شده است را اعتبارسنجی کنید، ساختار آن اینگونه است:

wp_verify_nonce( string $noncestring|int $action =  )

به منظور اعتبارسنجی مثالی که در تابع wp_nonce_url بررسی کردیم بدین صورت عمل می کنیم:

$nonce = $_GET[ 'token' ];
$post_id = $_GET[ 'post_id' ];
if ( ! wp_verify_nonce( $nonce, 'delete_my_post' ) ) {
  die('نانس نامعتبر است'); 
} else {
  // ادامه کار
}

 

خروجی تابع wp_verify_nonce یکی از مقادیر زیر می باشد:

  1. false: نانس نامعتبر است.
  2. مقدار یک: نانس معتبر است و کمتر از ۱۲ ساعت از ایجاد آن گذشته است(کوچکتر مساوی ۱۲ ساعت).
  3. مقدار دو: نانس معتبر است و بیشتر از ۱۲ ساعت از ایجاد آن گذشته است(بزرگتر از ۱۲ و کوچکتر مساوی ۲۴ ساعت).

۲-۲- check_admin_referer

از این تابع می توانید به عنوان یک روش جایگزین برای اعتبارسنجی نانس استفاده نمائید، ساختار تابع اینگونه است:

check_admin_referer( int|string $action = string $query_arg = ‘_wpnonce’ )

به منظور اعتبارسنجی مثالی که در تابع wp_nonce_field بررسی کردیم بدین صورت عمل می کنیم:

$nonce = $_POST[ 'st_token' ];
if ( ! check_admin_referer( 'my_secure_form', $nonce ) ) {
  die('نانس نامعتبر است'); 
} else {
  // ادامه کار
}

۳-۲- check_ajax_referer

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

check_ajax_referer( int|string $action = false|string $query_arg = falsebool $die = true )

با توجه به اینکه برای پیاده سازی ایجکس لازم است یکسری کارهای اضافی در وردپرس انجام دهید پیشنهاد می کنیم شیوه استفاده از این تابع را در مقاله آموزش استفاده از ایجکس(jQuery Ajax) در وردپرس(مثال استان و شهر) مطالعه فرمائید.

جمع بندی

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

نظرات و سوالات کاربران

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *