تم إصلاح الضعف الشديد في UpdraftPlus 1.22.3

نشرت: 2022-02-18

أثناء التدقيق الداخلي للمكوِّن الإضافي UpdraftPlus ، اكتشفنا ثغرة أمنية عشوائية في تنزيل النسخ الاحتياطي والتي قد تسمح للمستخدمين ذوي الامتيازات المنخفضة مثل المشتركين بتنزيل أحدث النسخ الاحتياطية الخاصة بالموقع.

إذا تم استغلال الثغرة الأمنية ، فقد تمنح المهاجمين حق الوصول إلى المعلومات المميزة من قاعدة بيانات الموقع المتأثر (على سبيل المثال ، أسماء المستخدمين وكلمات المرور المجزأة).

لقد أبلغنا مؤلفي المكون الإضافي بالثغرة الأمنية ، وأصدروا مؤخرًا الإصدار 1.22.3 لمعالجتها. تم أيضًا دفع التحديثات التلقائية الإجبارية بسبب خطورة هذه المشكلة. إذا لم يكن موقعك موجودًا بالفعل ، فنحن نوصي بشدة بالتحديث إلى أحدث إصدار (1.22.3) ولديك حل أمني ثابت على موقعك ، مثل Jetpack Security.

يمكنك العثور على النصائح الاستشارية الخاصة بـ UpdraftPlus هنا.

تفاصيل

اسم البرنامج المساعد: UpdraftPlus
عنوان URI للمكون الإضافي: https://wordpress.org/plugins/updraftplus/
المؤلف: https://updraftplus.com/

الضعف

تحميلات النسخ الاحتياطي التعسفي

الإصدارات المتأثرة: كل إصدار بين 1.16.7 و 1.22.3 (نسخة مجانية) ، و
معرف CVE: CVE-2022-0633
معرف WPVDB: d257c28f-3c7e-422b-a5c2-e618ed3c0bf3
CVSSv3.1: 8.5
CWSS: 87.6

يستخدم البرنامج المساعد "nonces" وطوابع زمنية مخصصة لتحديد النسخ الاحتياطية بشكل آمن. بالنظر إلى المعرفة الخاصة بـ nonce والطابع الزمني المذكورين ، يمكن أن يمنح شخص ما إمكانية الوصول إلى عدد قليل من ميزات المكون الإضافي ، من المهم التأكد من أن هذه المعلومات يمكن الوصول إليها فقط لأولئك الذين يحتاجون إليها بشكل شرعي.

لسوء الحظ ، كما سنوضح ، لم يكن الأمر كذلك.

نونسي تسرب

يقع الجاني الأول على UpdraftPlus_Admin :: process_status_in_heartbeat طريقة.

	/**
	 * Receive Heartbeat data and respond.
	 *
	 * Processes data received via a Heartbeat request, and returns additional data to pass back to the front end.
	 *
	 * @param array $response - Heartbeat response data to pass back to front end.
	 * @param array $data     - Data received from the front end (unslashed).
	 */
	public function process_status_in_heartbeat($response, $data) {
		if (!is_array($response) || empty($data['updraftplus'])) return $response;
		try {
			$response['updraftplus'] = $this->get_activejobs_list(UpdraftPlus_Manipulation_Functions::wp_unslash($data['updraftplus']));
		} catch (Exception $e) {
			$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
			error_log($log_message);
			$response['updraftplus'] = array(
				'fatal_error' => true,
				'fatal_error_message' => $log_message
			);
		// @codingStandardsIgnoreLine
		} catch (Error $e) {
			$log_message = 'PHP Fatal error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
			error_log($log_message);
			$response['updraftplus'] = array(
				'fatal_error' => true,
				'fatal_error_message' => $log_message
			);
		}

		if (UpdraftPlus_Options::user_can_manage() && isset($data['updraftplus']['updraft_credentialtest_nonce'])) {
			if (!wp_verify_nonce($data['updraftplus']['updraft_credentialtest_nonce'], 'updraftplus-credentialtest-nonce')) {
				$response['updraftplus']['updraft_credentialtest_nonce'] = wp_create_nonce('updraftplus-credentialtest-nonce');
			}
		}

		$response['updraftplus']['time_now'] = get_date_from_gmt(gmdate('Y-m-d H:i:s'), 'D, F j, Y H:i');

		return $response;
	}

لم تضمن بشكل صحيح أن المستخدم الذي أرسل طلب نبضات القلب هذا كان مسؤولاً (على سبيل المثال عبر وظائف مثل current_user_can) ، وكانت هذه مشكلة لأن أول شيء تحاول هذه الوظيفة القيام به هو الحصول على قائمة وظائف النسخ الاحتياطي النشطة عبر طريقة get_activejobs_list .

وبالتالي يمكن للمهاجم أن يصنع طلبًا ضارًا يستهدف رد اتصال نبضات القلب هذا للوصول إلى معلومات حول أحدث نسخة احتياطية للموقع حتى الآن ، والتي ستحتوي من بين أشياء أخرى على نسخة احتياطية.

تنزيل النسخ الاحتياطي

توجد عدة طرق لتنزيل النسخ الاحتياطية على UpdraftPlus ، وقد تم تأمين معظمها بشكل صحيح.

	/**
	 * Find out if the current request is a backup download request, and proceed with the download if it is
	 */
	public function maybe_download_backup_from_email() {
		global $pagenow;
		if ((!defined('DOING_AJAX') || !DOING_AJAX) && UpdraftPlus_Options::admin_page() === $pagenow && isset($_REQUEST['page']) && 'updraftplus' === $_REQUEST['page'] && isset($_REQUEST['action']) && 'updraft_download_backup' === $_REQUEST['action']) {
			$findexes = empty($_REQUEST['findex']) ? array(0) : $_REQUEST['findex'];
			$timestamp = empty($_REQUEST['timestamp']) ? '' : $_REQUEST['timestamp'];
			$nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce'];
			$type = empty($_REQUEST['type']) ? '' : $_REQUEST['type'];
			if (empty($timestamp) || empty($nonce) || empty($type)) wp_die(__('The download link is broken, you may have clicked the link from untrusted source', 'updraftplus'), '', array('back_link' => true));
			$backup_history = UpdraftPlus_Backup_History::get_history();
			if (!isset($backup_history[$timestamp]['nonce']) || $backup_history[$timestamp]['nonce'] !== $nonce) wp_die(__("The download link is broken or the backup file is no longer available", 'updraftplus'), '', array('back_link' => true));
			$this->do_updraft_download_backup($findexes, $type, $timestamp, 2, false, '');
			exit; // we don't need anything else but an exit
		}
	}
}

لسوء الحظ ، فإن طريقة UpdraftPlus_Admin :: might_download_backup_from_email ، المرتبطة بـ admin_init ، لم تتحقق مباشرة من أدوار المستخدمين أيضًا.

على الرغم من أنها طبقت بعض عمليات التحقق بشكل غير مباشر ، مثل التحقق من المتغير العالمي $ pagenow ، فقد أظهرت الأبحاث السابقة أن هذا المتغير يمكن أن يحتوي على مدخلات مستخدم عشوائية. يمكن للممثلين السيئين استخدام نقطة النهاية هذه لتنزيل نُسخ احتياطية من الملفات وقاعدة البيانات بناءً على المعلومات التي تم تسريبها من خطأ نبضات القلب المذكور أعلاه.

الجدول الزمني

2022-02-14 - الاتصال الأولي مع UpdraftPlus
2022-02-15 - نرسل لهم تفاصيل حول هذه الثغرة الأمنية
2022-02-16 - تم إصدار UpdraftPlus 1.22.3 ، وإطلاق التحديثات التلقائية الإجبارية

خاتمة

نوصيك بالتحقق من إصدار المكون الإضافي UpdraftPlus الذي يستخدمه موقعك ، وإذا كان ضمن النطاق المتأثر ، فقم بتحديثه في أقرب وقت ممكن!

في Jetpack ، نعمل بجد للتأكد من حماية مواقع الويب الخاصة بك من هذه الأنواع من الثغرات الأمنية. نوصي بأن يكون لديك خطة أمان لموقعك تتضمن فحص الملفات الضارة والنسخ الاحتياطي. Jetpack Security هو أحد خيارات الأمان الرائعة في WordPress لضمان أمان موقعك وزوارك.

الاعتمادات

الباحث الأصلي: مارك مونباس

شكرًا لبقية فريق Jetpack Scan على التعليقات والمساعدة والتصحيحات.