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

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

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

ضرب المثل معروفی است که می گوید: “علاج واقعه قبل از وقوع باید کرد”

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

نانس چیست؟

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

کلاینت هم برای انجام درخواست هایی مثل افزودن، حذف و ویرایش داده ها باید این نشانه امنیتی را به سرور برگرداند تا وردپرس مطمئن شود که درخواست های ارسالی جعلی(Fake) نیستند.

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

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

همانطور که در این تصویر ملاحظه می کنید وردپرس در هنگام انتقال یک پست به زباله دان رشته نانس را به انتهای URL اضافه کرده است.

رشته نانس nonce در وردپرس

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

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

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

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

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

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

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

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

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

فرآیند تولید و اعتبارسنجی نانس چگونه است؟

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

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

در صورتی که مکانیزم بالا به درستی پیاده سازی شود حمله 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. تولید نانس در هر جایی(URL، فرم های وب، عناصر HTML) توسط تابع wp_create_nonce

در دومین گام نانس تولیده شده باید اعتبارسنجی شود، برای این منظور می توانید از توابع زیر استفاده نمائید.

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

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

بررسی توابع تولید نانس در وردپرس

۱- تابع wp_nonce_url

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

در ساختار تابع wp_nonce_url سه پارامتر تعریف شده است که بدین صورت هستند.

wp_nonce_url( string $actionurl, int|string $action = -۱, string $name = '_wpnonce' )
  1. actionurl$ : آدرسی(URL) که نانس به انتهای آن اضافه خواهد شد(اجباری).
  2. action$ : نامی است که اکشن یا عملیات موردنظر را توصیف می کند و در هنگام اعتبارسنجی نانس مورد استفاده قرار می گیرد(اختیاری).
  3. name$ : با این پارامتر می توانید نام کلید نانس را تغییر دهید، به جای مقدار پیش فرض wpnonce_ مثلا از کلمه Token استفاده کنید(اختیاری).

در این مثال برای حذف یک پست از تابع wp_nonce_url استفاه کردیم.

$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="' . esc_attr( $nonce_url ) . '">Delete Post</a>';

$admin_url = admin_url( 'post.php?action=delete' );

خروجی کدهای بالا بدین صورت خواهد بود، به انتهای URL توجه کنید.

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

۲- تابع wp_nonce_field

دومین تابعی که برای ایجاد نانس استفاده می کنیم wp_nonce_field است، تابع فوق در فرم های HTML دو فیلد Input مخفی(Hidden) تولید می کند، یکی برای نگهداری رشته نانس و دیگری برای آدرس ارجاع دهنده.

ساختار wp_nonce_field بدین صورت است.

wp_nonce_field( int|string $action = -۱, string $name = "_wpnonce", 
                 bool $referer = true, bool $echo = true )
  1. action$ : نامی است که عملیات موردنظر را توصیف کرده و در زمان اعتبارسنجی نانس استفاده خواهد شد(اختیاری).
  2. name$ : همانطور که در تابع قبلی گفتیم از این پارامتر برای تغییر نام کلید پیش فرض نانس استفاده می شود(اختیاری).
  3. referer$ : اگر این پارامتر false باشد فیلد hidden ارجاع دهنده تولید نمی شود(اختیاری).
  4. echo$ : اگر این پارامتر false باشد هیچکدام از فیلدها در خروجی نشان داده نمی شوند(اختیاری).

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

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

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

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

<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

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

wp_create_nonce( string|int $action = -۱ )

۱- action$ : عملیات موردنظر را توصیف کرده و در هنگام اعتبارسنجی کاربرد دارد(اختیاری).

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

$my_nonce = wp_create_nonce( 'edit_record' );

<form method="post" action="">
    <input type="hidden" id="nonce_form" name="nonce_form" 
            value="<?php echo esc_attr( $my_nonce ) ?>">
    <input type="submit" value="ارسال">
</form>

بررسی توابع اعتبارسنجی نانس در وردپرس

مهمترین کاری که پس از تولید Nonce باید انجام دهیم اعتبارسنجی درخواست های کاربران در سمت سرور است.

۱- تابع wp_verify_nonce

به کمک این تابع می توانید نانس موجود در درخواست ها را اعتبارسنجی کنید، ساختار wp_verify_nonce اینگونه است.

wp_verify_nonce( string $nonce, string|int $action = -۱ )

برای درک بهتر موضوع مثالی که در تابع wp_nonce_url تعریف کردیم را با تابع wp_verify_nonce بدین صورت اعتبارسنجی می کنیم.

$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 اینگونه است.

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 بدین صورت است.

check_ajax_referer( int|string $action = -۱, false|string $query_arg = false, 
                    bool $die = true )

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

جمع بندی

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

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

پیشنهاد می کنیم حتما نمونه های واقعی از پیاده سازی نانس را بررسی و آنالیز کنید، برای این منظور می توانید از آموزش های زیر شروع کنید:

  1. آموزش اعتبارسنجی درخواست های ایجکس از طریق نانس(Nonce)
  2. آموزش ساخت پنل تنظیمات در وردپرس بدون Settings API

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

دیدگاهتان را بنویسید

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