Patreon WordPress 插件中發現的漏洞

已發表: 2021-03-26

在對 WordPress 的 Patreon 插件進行內部審計期間,Jetpack Scan 團隊發現了幾個弱點,這些弱點會允許某人接管一個網站。

這些漏洞已披露給插件作者,他們立即發布了 1.7.2 版,修復了所有這些問題。 如果您正在運行舊版本的插件,請立即更新!

請繼續閱讀以了解所有技術細節。 如果這超出了您的想像,請不要擔心。 我們提供 Jetpack Scan 來為您處理惡意軟件掃描和自動升級或刪除。

我們的團隊確定了各種攻擊媒介,包括本地文件洩露、跨站點請求偽造 (CSRF) 和反射跨站點腳本 (XSS) 漏洞。

本地文件洩露漏洞是不良行為者可以用來訪問關鍵信息的錯誤,例如網站的密鑰和數據庫憑據。 反射的跨站點腳本和跨站點請求偽造漏洞是攻擊者能夠通過誘使他們單擊精心製作的惡意鏈接來代表毫無戒心的用戶執行特定操作的問題。

如果被利用,其中一些可能會使惡意個人接管易受攻擊的網站。

本地文件洩露漏洞
受影響的版本: < 1.7.0
CVE ID: CVE-2021-24227
CVSSv3: 7.5
CWSS: 83.6

	public static function servePatronOnlyImage( $image=false ) {

		if ( ( !isset( $image ) OR !$image ) AND isset( $_REQUEST['patron_only_image'] ) ) {
			$image = $_REQUEST['patron_only_image'];
		}
		
		if ( !$image OR $image == '') {
			// This is not a rewritten image request. Exit.
			return;
		}

		if ( !( isset( $_REQUEST['patreon_action'] ) AND $_REQUEST['patreon_action'] == 'serve_patron_only_image' ) ) {
			return;	
		}

		$upload_locations = wp_upload_dir();

		// We want the base upload location so we can account for any changes to date based subfolders in case there are

		$upload_dir = substr( wp_make_link_relative( $upload_locations['baseurl'] ) , 1 );	

		$image = get_site_url() . '/' . $upload_dir . '/' . $image;
		
		if ( current_user_can( 'manage_options' ) ) {
			Patreon_Protect::readAndServeImage( $image );	
		}			
		
		// Below define can be defined in any plugin to bypass core locking function and use a custom one from plugin
		// It is independent of the plugin load order since it checks if it is defined.
		// It can be defined by any plugin until right before the_content filter is run.

		if ( apply_filters( 'ptrn/bypass_image_filtering', defined( 'PATREON_BYPASS_IMAGE_FILTERING' ) ) ) {
			Patreon_Protect::readAndServeImage( $image );
		}
	
		// Check if the image is protected:

		$attachment_id = attachment_url_to_postid( $image );
	
		// attachment_url_to_postid returns 0 if it cant find the attachment post id
		
		if ( $attachment_id == 0 ) {
			
			// Couldnt determine attachment post id. Try to get id from thumbnail
			$attachment_id = Patreon_Protect::getAttachmentIDfromThumbnailURL( $image );
	
			//No go. Have to get out and serve the image normally
			if ( $attachment_id == 0 OR !$attachment_id ) {
				Patreon_Protect::readAndServeImage( $image );

Patreon-Connect 包含一個本地文件洩露漏洞,任何訪問該站點的人都可能濫用該漏洞。 使用此攻擊向量,攻擊者可以洩露重要的內部文件,如 wp-config.php,其中包含用於生成隨機數和 cookie 的數據庫憑據和加密密鑰。

如果成功利用,此安全漏洞可能會導致不法分子完全接管網站。

登錄表單上的反射 XSS
受影響的版本: < 1.7.2
CVE ID: CVE-2021-24228
CVSSv3: 8.8
CWSS: 80.6

	public static function processPatreonMessages() {
		
		$patreon_error = '';
		if ( isset( $_REQUEST['patreon_error'] ) ) {
			
			// If any specific error message is sent from Patreon, prepare it
			$patreon_error = ' - Patreon returned: ' . $_REQUEST['patreon_error'];
			
		}

		if ( isset( $_REQUEST['patreon_message'] ) ) {
			
			return '<p class="patreon_message">' . apply_filters( 'ptrn/error_message', self::$messages_map[ $_REQUEST['patreon_message'] ] . $patreon_error ) . '</p>';

Patreon-Connect 掛鉤 WordPress 登錄表單 (wp-login.php),並允許用戶使用他們的 Patreon 帳戶在網站上進行身份驗證。 不幸的是,場景背後的一些錯誤記錄邏輯允許用戶控制的輸入反映在登錄頁面上,未經處理。

要成功利用此漏洞,攻擊者需要誘騙受害者訪問包含惡意 Javascript 代碼的誘殺鏈接。 由於 Javascript 在受害者的瀏覽器上下文中運行,攻擊者可以調整隱藏在該鏈接中的代碼,以執行該用戶權限允許他執行的任何操作。

如果此攻擊成功針對管理員,則該腳本可以完全接管該站點。

在 AJAX 操作“patreon_save_attachment_patreon_level”上反映 XSS
受影響的版本: < 1.7.2
CVE ID: CVE-2021-24229
CVSSv3: 8.8
CWSS: 80.6

		$args = array (
			'attachment_id' => $attachment_id,
			'patreon_level' => $_REQUEST['patreon_attachment_patreon_level'],
			'message' => $message,
		);
		
		echo self::make_image_lock_interface( $args	);
	public function make_image_lock_interface( $args = array() ) {
		
		$interface = '';
		
		$interface .=  '<div class="patreon_image_lock_modal_content">';
		$interface .=  '<span class="patreon_image_lock_modal_close">&times;</span>';

		$interface .=  ' <form id="patreon_attachment_patreon_level_form" action="/wp-admin/admin-ajax.php" method="post">';
		$interface .=  '<h1 class="patreon_image_locking_interface_heading">Lock Image</h1>';
		$interface .=  '<div class="patreon_image_locking_interface_level">';
		$interface .=  '<span class="patreon_image_locking_interface_input_prefix">$<input id="patreon_attachment_patreon_level" type="text" name="patreon_attachment_patreon_level" value="' . $args['patreon_level'] . '" / ></span>';

該插件還使用 AJAX 掛鉤來更新 Patreon 訂閱者訪問給定附件所需的承諾級別。 具有“manage_options”權限的用戶帳戶(即只有管理員)可以訪問此操作。

不幸的是,這個 AJAX 端點中使用的參數之一在打印回用戶之前沒有經過清理,因此它所代表的風險與我們之前描述的 XSS 漏洞相同。

CSRF 允許攻擊者覆蓋/創建用戶元
受影響的版本: < 1.7.0
CVE ID: CVE-2021-24230
CVSSv3: 6.5
CWSS: 42

	public function toggle_option() {
		
		if( !( is_admin() && current_user_can( 'manage_options' ) ) ) {
			return;
		}
		
		$current_user = wp_get_current_user();
		
		$option_to_toggle = $_REQUEST['toggle_id'];
		
		$current_value = get_user_meta( $current_user->ID, $option_to_toggle, true );
		
		$new_value = 'off';
		
		if( !$current_value OR $current_value == 'off' ) {
			$new_value = 'on';			
		}
		
		update_user_meta( $current_user->ID, $option_to_toggle, $new_value );
		
	}

一些端點沒有驗證它收到的請求是根據用戶的合法操作發送的,您可以使用 nonce 來執行此操作。 這些未受保護的端點之一允許惡意個人製作一個誘殺鏈接,一旦訪問,該鏈接將覆蓋或創建受害者帳戶上的任意用戶元數據。

如果被利用,此漏洞可用於覆蓋“wp_capabilities”元數據,其中包含受影響用戶帳戶的角色和權限。 這樣做基本上會將他們鎖定在網站之外,阻止他們訪問付費內容。

CSRF 允許攻擊者斷開站點與 Patreon 的連接
受影響的版本: < 1.7.0
CVE ID :CVE-2021-24231
CVSSv3: 6.5
CWSS: 26.1

			if ( isset( $_REQUEST['patreon_wordpress_action'] ) AND $_REQUEST['patreon_wordpress_action'] == 'disconnect_site_from_patreon' AND is_admin() AND current_user_can( 'manage_options' ) ) {

			// Admin side, user is admin level. Perform action:
			
			// To disconnect the site from a particular creator account, we will delete all options related to creator account, but we will leave other plugin settings and post gating values untouched
			
			$options_to_delete = array(
				'patreon-custom-page-name',
				'patreon-fetch-creator-id',
				'patreon-creator-tiers',
				'patreon-creator-last-name',
				'patreon-creator-first-name',
				'patreon-creator-full-name',
				'patreon-creator-url',
				'patreon-campaign-id',
				'patreon-creators-refresh-token-expiration',
				'patreon-creator-id',
				'patreon-setup-wizard-last-call-result',
				'patreon-creators-refresh-token',
				'patreon-creators-access-token',
				'patreon-client-secret',
				'patreon-client-id',
				'patreon-setup_is_being_done',
				'patreon-setup-done',
				'patreon-currency-sign',
			);
			
			// Ask the API to delete this client:
			
			$creator_access_token = get_option( 'patreon-creators-access-token', false );
			$client_id 			  = get_option( 'patreon-client-id', false );
				
			// Exceptions until v1 v2 transition is complete
			
			$api_version = get_option( 'patreon-installation-api-version' );

			if ( $api_version == '1' ) {

				// Delete override - proceed with deleting local options
				
				foreach ( $options_to_delete as $key => $value ) {
					delete_option( $options_to_delete[$key] );
				}
				
				update_option( 'patreon-installation-api-version', '2' );
				update_option( 'patreon-can-use-api-v2', true );
				
				wp_redirect( admin_url( 'admin.php?page=patreon_wordpress_setup_wizard&setup_stage=reconnect_0') );
				exit;
			}
			

這個漏洞與上一個漏洞相似,因為它是同一種攻擊 (CSRF),但針對的是管理員。 這個特定的攻擊向量與之前的一樣。 攻擊者需要登錄管理員才能訪問特製鏈接。

由於此特定端點可以斷開站點與 Patreon 的連接,因此針對此攻擊媒介的攻擊者也可以這樣做,這將阻止新內容同步到站點。

時間線

  • 初次聯繫嘗試(不成功)– 12 月 4 日
  • 第二次聯繫嘗試 – 12 月 11 日
  • 作者承認報告 - 12 月 15 日
  • 1.7.0 版發布 – 1 月 5 日
  • 我們報告了另外兩個 XSS 問題——3 月 9 日
  • 作者承認第二份報告 – 3 月 9 日
  • 1.7.2 版發布 – 3 月 11 日

結論

我們建議您檢查您在網站上使用的 Patreon-Connect 插件的當前版本,如果不是 1.7.2,請盡快更新!

在 Jetpack,我們努力確保您的網站免受此類漏洞的影響。 要領先任何新威脅一步,請查看 Jetpack Scan,其中包括安全掃描和自動惡意軟件刪除。

學分

多虧了 George Stephanis、Fioravante Souza、Miguel Neto、Benedict Singer 和 Marc Montpas,這項安全披露才得以實現。