سلام دوستان عزیز ، در این مقاله از آموزش وردپرس ، در مورد روش های اعتبارسنجی Validation و پاکسازی Sanitization مقادیر ورودی در وردپرس بحث می کنیم .

مقدمه:

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

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

به هیچ چیزی اعتماد نداشته باشید

اعتبارسنجی Validation به صورت عامیانه یعنی داده ای که ما با اون کار میکنیم وجود داره و همون چیزی هستش که ما انتظارش رو داریم.

پاکسازی Sanitization در کل یعنی آماده کردن داده جهت ارسال به Database و اطمینان از سالم بودن داده جهت ثبت.

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

اعتبارسنجی Client-Side vs. Server-Side

رایج ترین راه ثبت اطلاعات در وردپرس Submit کردن فرم توسط کاربر ، اسکریپت ، وب سرویس ، app و… است. اعتبارسنجی سمت کاربر Client-Side باید در زمان ارسال فرم انجام شود و مانع از ارسال داده های ناقص یا مخرب گردد

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

اعتبار سنجی بخش اول : مجاز بودن

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

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

در ادامه مثالی از یک درخواست POST رو مشاهده می کنید که ابتدا وجود و اعتبارسنجی nonce انجام شده و سپس بررسی میکنیم که کاربر مورد نظر قابلیت خاصی رو داره یا خیر :

if( isset( $_POST[ '_wpnonce' ] ) && wp_verify_nonce( $_POST[ '_wpnonce' ] ) ){
    if( current_user_can( 'some_capability' ) ){
 
    }
}

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

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

در زمان دریافت هر نوع داده ای از کاربر در قالب GET یا POST ،باید مطمئن بشیم که فیلدهای مورد انتظار موجود بوده و مقداردهی شده باشند، در ادامه نحوه چک کردن فیلد دریافتی را به کدهای قبلی اضافه کردیم:

if( isset( $_POST[ '_wpnonce' ] ) && wp_verify_nonce( $_POST[ '_wpnonce' ] ) ){
    if( current_user_can( 'some_capability' ) ) {
        if( isset( $_POST[ 'number_of_thing' ] )  ){
 
        }
    }
}

در مثال زیر تابعی داریم که با دریافت post_id و یک آرایه، مقادیر دو متا فیلد رو تغییر میده ، جهت اعتبارسنجی قبل از تغییر مقادیر متا فیلد ها ، مقادیر آرایه را بررسی می کنیم:

function slug_something( $post_id, $data ){
 
    if ( isset( $data[ 'bar' ], $data[ 'foo' ] ) ) {
        update_post_meta( $post_id, 'foo', $data[ 'foo' ] );
        update_post_meta( $post_id, 'bar', $data[ 'bar' ] );
    }
 
}

اعتبارسنجی بخش سوم: فرمت بندی صحیح

در PHP متغیر ها دارای نوع می باشند (object, string, integer, float, array,…) ، ولی لازم نیست نوع متغیرها رو معرفی کنیم چون زبان PHP یک زبان dynamically typed و نوع متغییرها در هنگام اجرای برنامه می تونه تغییر کنه ، مثل کدهای زیر:

$foo = 'bar';
$foo = array( 'bar', 'foo' );

متغیر foo ابتدا به عنوان رشته تعریف شده و سپس به یک آرایه تبدیل میشود.

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

تابع زیر را در نظر بگیرید:

function slug_display_status( $post ) {
    echo $post->post_status;
}

این تابع تا زمانی که $post یک object از کلاس WP_Post باشد و مقدار $post_status معتبر باشد به درستی کار می کند.

ممکن است در تابع بالا بجای object یک مقدار عددی مانند id یک پست ارسال شود ، تابع ما یا باید پیام خطای مناسب نمایش دهد و یا باید از قبل پیش بینی چنین شرایطی را کرده و کد لازم جهت درست کار کردن تابع را در آن قرار دهیم مانند کد زیر :

function slug_display_status( $post ) {
    if ( is_numeric( $post ) ) {
        $post = get_post( $post );
    }
 
    if ( is_object( $post ) && isset( $post->post_status ) ) {
        echo $post->post_status;
    }
 
}

در کد بالا ما علاوه بر اینکه از صحت object بودن $post و از معتبر بودن مقدار post_satatus اطمینان حاصل می کنیم، با پیش بینی ارسال عدد به جای object ، کد لازم جهت بدست آوردن object مرتبط با id ارسالی را نیز در نظر گرفته ایم، حالا تابع ما در هر دو صورت با ارسال object یا id مرتبط با پست به درستی کار می کند.

جمع بندی اعتبارسنجی :

در شرایطی یک درخواست HTTP دریافت می کنیم تمام موارد بالا باید رعایت شود ، برای مثال در هنگام دریافت یک درخواست که شامل  post ID, array, nonce هستش به ترتیب اعتبارسنجی های لازم مانند قطعه کد زیر را انجام داده و در صورت نامعتبر بودن پیام مناسب نمایش داده و کد خطای مربوطه را به کاربر ارسال می کنیم:

if( isset( $_POST[ '_wpnonce' ] ) && wp_verify_nonce( $_POST[ '_wpnonce' ] ) ){
    if( current_user_can( 'some_capability' ) ) {
        if( ! isset( $_POST[ 'post_id' ] )  || ! is_numeric( $_POST[ 'post_id' ] ) || ! is_object( get_post( $_POST[ 'post_id' ] ) ) ) {
            status_header( '400' );
            echo "post_id must be set and represent a valid post";
            die();
    }elseif( ! isset( $_POST[ 'data' ] ) || ! is_array( $_POST[ 'data' ] ) || ! isset( $_POST[ 'data' ][ 'foo' ], $_POST[ 'data' ][ 'foo' ] ) ) {
            status_header( '400' );
            echo 'data must be set and be an array containing the keys "foo" and "bar"';
            die();
        }else{
            //request is valid
        }
    } else {
        status_header( '403' );
        die();
    }
} else {
    status_header( '401' );
    die();
}

پاکسازی Sanitization :

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

فرض کنید که میخوایم یک رشته رو ذخیره کنیم، آیا باید هر رشته دریافتی رو قبول کنیم؟ آیا باید رشته ای که حاوی کدهای Javascript  و MySQL است رو قبول کنیم؟

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

var_dump( is_email( '1@hats.com' ) ); //true
var_dump( is_email( 'x' ) ); //false
var_dump( sanitize_email( '1@' ) ); // ''
var_dump( sanitize_email( '1@ha^ts.com' ) ); //1@hats.com
var_dump( sanitize_email( '1@hats.com' ) ); //1@hats.com

در دو مثال اول ما اعتبارسنجی انجام میدیم که آیا مقادیر وارد شده ایمیل هستند یا خیر ، و در سه مثال بعدی داریم مقادیر رو تبدیل به محتوای سالم جهت ذخیره Database می کنیم.

در تابع زیر اعتبارسنجی و پاکسازی را در کنار هم قرار دادیم:

function slug_save_email( $email ) {
    if ( is_email( $email ) ) {
        $email = sanitize_email( $email );
        //you may now save $email;
    }
}

وردپرس پر از توابع پاکسازی هستش که می تونه به شما کمک کنه و تابع sanitize_email فقط یکی از این توابع است،  خیلی از این توابع رو می تونید در wp-includes/formatting.php پیدا کنید.

حرف آخر – اعتبارسنجی و پاکسازی مقادیر ورودی در وردپرس :

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

اگر مشکلی و یا سوالی در مورد مقاله وجود داشت خوشحال میشویم که در قسمت نظرات همین مطلب پاسخگو باشیم.

موفق و پیروز باشید.

دیدگاه خود را بیان کنید

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

-- بارگیری کد امنیتی --