Input Validation در وردپرس (اعتبارسنجی ورودی) چطور انجام می‌شود؟ این پرسشی است که هر توسعه‌دهنده وردپرسی باید پاسخ دقیق آن را بداند. Input Validation (اعتبارسنجی ورودی) فرآیند بررسی داده‌های ورودی قبل از پردازش است تا اطمینان حاصل شود که داده با فرمت، نوع و محدوده مورد انتظار مطابقت دارد. برخلاف Sanitization که داده را «پاک» می‌کند، Validation داده را «رد یا قبول» می‌کند. وردپرس مجموعه‌ای از توابع اعتبارسنجی مانند is_email()، is_numeric()، validate_file() و توابع sanitize_* با پارامترهای اعتبارسنجی را فراهم کرده است. در REST API، پارامتر validate_callback امکان اعتبارسنجی دقیق ورودی را می‌دهد. اما چرا Input Validation در وردپرس اغلب نادیده گرفته می‌شود؟ دلایلی مانند اتکای صرف به Sanitization، عدم آگاهی از تفاوت Validation و Sanitization، و فشار زمانی پروژه‌ها. پیامدهای نادیده گرفتن Validation می‌تواند از ذخیره داده نامعتبر در پایگاه داده تا اجرای حملاتی مانند SQL Injection، XSS و حتی RCE متغیر باشد. در این نوشتار، از ریشه‌های فنی تا پیاده‌سازی عملی Input Validation در وردپرس را بررسی می‌کنیم.

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

Input Validation چیست؟

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

دو رویکرد اصلی در Input Validation وجود دارد:

  • Allowlist (لیست سفید): فقط مقادیر مشخص و از پیش تعریف‌شده پذیرفته می‌شوند. مطمئن‌ترین رویکرد.
  • Denylist (لیست سیاه): مقادیر خطرناک مسدود می‌شوند. همیشه قابل دور زدن است.

رویکرد Allowlist همیشه ارجح است. برای درک عمیق‌تر جایگاه این مفهوم در امنیت وب، اصول امنیت وب را ببینید.

Input Validation یک «دروازه» است: اگر داده از این دروازه نگذرد، هرگز به لایه‌های بعدی نمی‌رسد. این دقیقاً همان چیزی است که بسیاری از پروژه‌ها از آن غافل‌اند.

تفاوت Validation و Sanitization

ویژگیValidationSanitization
هدفرد یا قبول دادهپاک‌سازی داده
خروجیBoolean یا خطاداده پاک
زمان اجرااولین لایهپس از Validation
رفتار در خطارد دادهاصلاح داده
کاربرد اصلیورودی‌های ساخت‌یافته (ایمیل، عدد، تاریخ)ورودی‌های آزاد (متن، HTML)

جمع‌بندی این مقایسه ساده است: Validation می‌گوید «این داده را قبول می‌کنم یا نه»، و Sanitization می‌گوید «این داده را چطور بی‌خطر کنم». بهترین رویکرد، ترکیب هر دو است. برای درک عمیق‌تر Sanitization، پاک‌سازی داده‌ها در کدنویسی وردپرس را ببینید.

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

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

تابعکاربرد
is_email()بررسی اعتبار ایمیل
is_numeric()بررسی عددی بودن
validate_file()بررسی مسیر فایل
wp_validate_boolean()تبدیل به boolean
rest_validate_request_arg()اعتبارسنجی پارامتر REST
is_wp_error()بررسی خطای وردپرس

علاوه بر این، توابع sanitize_* مانند sanitize_email()، sanitize_text_field()، absint() و intval() نیز در اعتبارسنجی نقش دارند. برای درک عمیق‌تر، اعتبارسنجی داده‌ها در کدنویسی وردپرس را ببینید.

اعتبارسنجی در REST API

در REST API وردپرس، هر پارامتر می‌تواند validate_callback و sanitize_callback داشته باشد:

register_rest_route( 'myplugin/v1', '/user', [
  'methods' => 'POST',
  'callback' => 'myplugin_create_user',
  'permission_callback' => function() {
    return current_user_can( 'manage_options' );
  },
  'args' => [
    'email' => [
      'required' => true,
      'validate_callback' => function( $param ) {
        return is_email( $param );
      },
      'sanitize_callback' => 'sanitize_email',
    ],
    'age' => [
      'validate_callback' => function( $param ) {
        return is_numeric( $param ) && $param >= 18 && $param <= 120;
      },
      'sanitize_callback' => 'absint',
    ],
  ],
] );

این رویکرد «اعتبارسنجی مبتنی بر شِما» را ممکن می‌کند و از همان ابتدا داده‌های نامعتبر را رد می‌کند. برای درک عمیق‌تر، استفاده از REST API در وردپرس را ببینید.

چرا Input Validation حیاتی است؟

Input Validation اولین خط دفاعی در برابر بسیاری از حملات است:

  • SQL Injection: اگر داده ورودی عددی باشد و شما آن را با absint() اعتبارسنجی کنید، حمله غیرممکن می‌شود.
  • XSS: اگر داده ورودی از نوع HTML مجاز نباشد، اعتبارسنجی سختگیرانه می‌تواند XSS را مسدود کند.
  • File Inclusion: اعتبارسنجی مسیر فایل با whitelist، از حمله جلوگیری می‌کند.
  • DoS: محدودسازی طول ورودی، از انفجار حافظه جلوگیری می‌کند.
  • داده نامعتبر: جلوگیری از ذخیره داده‌های بی‌معنا در پایگاه داده.

نکته مهم این است که Input Validation به‌تنهایی کافی نیست، اما بدون آن، سایر لایه‌های دفاعی نیز بی‌اثر می‌شوند. برای مرور انواع آسیب‌پذیری‌های مرتبط، انواع آسیب‌پذیری‌های رایج وب را ببینید.

پیاده‌سازی عملی در افزونه و قالب

سه سطح اصلی برای پیاده‌سازی Input Validation وجود دارد:

سطح ۱: فرم‌های HTML

$email = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : '';
if ( ! is_email( $email ) ) {
  wp_die( 'ایمیل نامعتبر است' );
}

$age = isset( $_POST['age'] ) ? absint( $_POST['age'] ) : 0;
if ( $age < 18 || $age > 120 ) {
  wp_die( 'سن نامعتبر است' );
}

سطح ۲: AJAX Handlers

add_action( 'wp_ajax_myplugin_save', function() {
  check_ajax_referer( 'myplugin_nonce', 'nonce' );
  
  $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
  if ( ! $post_id || ! get_post( $post_id ) ) {
    wp_send_json_error( 'شناسه نامعتبر' );
  }
  
  $status = isset( $_POST['status'] ) ? sanitize_key( $_POST['status'] ) : '';
  $allowed = ['draft', 'publish', 'pending'];
  if ( ! in_array( $status, $allowed, true ) ) {
    wp_send_json_error( 'وضعیت نامعتبر' );
  }
  
  // پردازش
  wp_send_json_success();
} );

سطح ۳: REST API

همان‌طور که در بخش قبل دیدیم، استفاده از validate_callback و sanitize_callback بهترین رویکرد است.

برای درک عمیق‌تر ساختار کد امن، نوشتن کد PHP امن برای وردپرس را ببینید.

اشتباهات رایج در Input Validation

  • اتکای صرف به Sanitization: Sanitization داده را اصلاح می‌کند، اما داده نامعتبر را رد نمی‌کند.
  • استفاده از Denylist به‌جای Allowlist: Denylist همیشه دور زده می‌شود.
  • اعتبارسنجی سمت کلاینت تنها: مهاجم می‌تواند JavaScript را غیرفعال کند.
  • فراموش کردن اعتبارسنجی سمت سرور: حتی اگر اعتبارسنجی سمت کلاینت باشد، سمت سرور ضروری است.
  • نادیده گرفتن نوع داده: بررسی نکردن اینکه داده رشته است یا عدد.
  • عدم محدودسازی طول: ورودی‌های بسیار طولانی می‌توانند DoS ایجاد کنند.
  • نادیده گرفتن فایل‌های آپلودی: بررسی نوع MIME، اندازه و محتوا ضروری است.
  • اعتماد به $_REQUEST: این متغیر ترکیبی از GET، POST و COOKIE است و باید با احتیاط استفاده شود.

برای مرور خطاهای مشابه در پیکربندی، اشتباهات امنیتی رایج در وردپرس را ببینید.

پرسش‌های پرتکرار درباره Input Validation

آیا Input Validation به‌تنهایی برای امنیت کافی است؟ نه، باید با Sanitization، Output Escaping و CSP ترکیب شود تا دفاع چندلایه ایجاد گردد.

تفاوت sanitize_email() و is_email() چیست؟ اولی ایمیل را پاک می‌کند و دومی فقط بررسی می‌کند که ایمیل معتبر است یا نه. بهترین رویکرد، استفاده از هر دو است.

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

چطور بفهمم فرم من Input Validation دارد؟ کد فرم را جست‌وجو کنید. هر جا داده‌ای از $_POST یا $_GET خوانده می‌شود، باید قبل از پردازش اعتبارسنجی شود.

آیا اعتبارسنجی سمت کلاینت بی‌فایده است؟ نه، برای تجربه کاربری مفید است، اما به‌تنهایی کافی نیست و باید با اعتبارسنجی سمت سرور ترکیب شود.

برای مطالعه بیشتر درباره این مفهوم، صفحه Data validation در ویکی‌پدیا مفید است.

خط پایان

Input Validation یکی از آن لایه‌های امنیتی است که در سایه Sanitization و Output Escaping کمتر دیده می‌شود، اما در واقع «دروازه اول» است. اگر داده از این دروازه نگذرد، هرگز به لایه‌های بعدی نمی‌رسد و حمله متوقف می‌شود. در بستر وردپرس، توابع اعتبارسنجی متعددی وجود دارد که بسیاری از آن‌ها نادیده گرفته می‌شوند. دفاع مؤثر نیازمند ترکیب Allowlist، بررسی نوع و طول داده، اعتبارسنجی سمت سرور و استفاده از validate_callback در REST API است. اگر سایت شما فرم یا endpoint دارد، همین امروز کد را بازبینی کنید.

اگر در پروژه‌ای با حمله ناشی از عدم Input Validation روبه‌رو شده‌اید یا راهکار متفاوتی پیاده کرده‌اید، تجربه خود را در دیدگاه‌ها بنویسید؛ به‌خصوص اگر افزونه یا قالب خاصی عامل بوده، این اطلاعات برای خواننده بعدی بسیار ارزشمند است.