Vulnerabilità riscontrate nel plugin WordPress di Patreon

Pubblicato: 2021-03-26

Durante un audit interno del plug-in Patreon per WordPress, il team di Jetpack Scan ha riscontrato diversi punti deboli che consentirebbero a qualcuno di rilevare un sito Web.

Queste vulnerabilità sono state divulgate agli autori del plugin, che hanno prontamente rilasciato la versione 1.7.2, che risolve tutti questi problemi. Se stai utilizzando una versione precedente del plug-in, aggiorna oggi stesso!

Continua a leggere per tutti i dettagli tecnici. Se questo ti passa per la testa, non preoccuparti. Offriamo Jetpack Scan per gestire la scansione del malware e gli aggiornamenti o la rimozione automatizzati per te.

Il nostro team ha identificato vari vettori di attacco, tra cui le vulnerabilità di Local File Disclosure, Cross-Site Request Forgery (CSRF) e Reflected Cross-Site Scripting (XSS).

Le vulnerabilità di Local File Disclosure sono bug che i malintenzionati possono utilizzare per accedere a informazioni critiche, come le chiavi segrete di un sito Web e le credenziali del database. Le vulnerabilità di Cross-Site Scripting riflessa e Richieste Cross-Site False sono problemi che consentono agli aggressori di eseguire azioni specifiche per conto di utenti ignari inducendoli a fare clic su collegamenti dannosi accuratamente predisposti.

Se sfruttati, alcuni di questi potrebbero consentire a persone malintenzionate di assumere il controllo di siti Web vulnerabili.

Vulnerabilità di divulgazione di file locali
Versioni interessate: < 1.7.0
ID CVE: CVE-2021-24227
CVSSv3: 7.5
CCSS: 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 conteneva una vulnerabilità di divulgazione di file locali che poteva essere abusata da chiunque visitasse il sito. Utilizzando questo vettore di attacco, un utente malintenzionato potrebbe divulgare importanti file interni come wp-config.php, che contiene le credenziali del database e le chiavi crittografiche utilizzate nella generazione di nonce e cookie.

Se sfruttato con successo, questo difetto di sicurezza potrebbe portare a una completa acquisizione del sito da parte di malintenzionati.

XSS riflesso nel modulo di accesso
Versioni interessate: < 1.7.2
ID CVE: CVE-2021-24228
CVSSv3: 8.8
CCSS: 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 si aggancia al modulo di accesso di WordPress (wp-login.php) e offre la possibilità agli utenti di autenticarsi sul sito utilizzando il proprio account Patreon. Sfortunatamente, parte della logica di registrazione degli errori dietro le quinte ha consentito che l'input controllato dall'utente si riflettesse sulla pagina di accesso, non disinfettata.

Per sfruttare con successo questa vulnerabilità, un utente malintenzionato deve indurre la sua vittima a visitare un collegamento esplosivo contenente codice Javascript dannoso. Poiché Javascript viene eseguito nel contesto del browser della vittima, un utente malintenzionato può modificare il codice nascosto in quel collegamento per fare qualsiasi cosa gli consentano i privilegi di questo utente.

Se questo attacco ha esito positivo contro un amministratore, lo script può occupare completamente il sito.

XSS riflesso sull'azione AJAX 'patreon_save_attachment_patreon_level'
Versioni interessate: < 1.7.2
ID CVE: CVE-2021-24229
CVSSv3: 8.8
CCSS: 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>';

Il plug-in utilizza anche un hook AJAX per aggiornare il livello di impegno richiesto dagli abbonati Patreon per accedere a un determinato allegato. Questa azione è accessibile per gli account utente con il privilegio 'manage_options' (ad esempio, solo gli amministratori).

Sfortunatamente, uno dei parametri utilizzati in questo endpoint AJAX non viene disinfettato prima di essere ristampato all'utente, quindi il rischio che rappresenta è lo stesso della precedente vulnerabilità XSS che abbiamo descritto.

CSRF che consente agli aggressori di sovrascrivere/creare meta utente
Versioni interessate: < 1.7.0
ID CVE: CVE-2021-24230
CVSSv3: 6.5
CSSS: 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 );
		
	}

Alcuni endpoint non hanno convalidato la richiesta che ha ricevuto è stata inviata a seguito di un'azione legittima da parte di un utente, che puoi eseguire utilizzando nonces. Uno di questi endpoint non protetti ha consentito a individui malevoli di creare un collegamento esplosivo che avrebbe sovrascritto o creato metadati utente arbitrari sull'account della vittima una volta visitato.

Se sfruttato, questo bug può essere utilizzato per sovrascrivere il meta "wp_capabilities", che contiene i ruoli ei privilegi dell'account utente interessato. Ciò li bloccherebbe essenzialmente fuori dal sito, impedendo loro di accedere ai contenuti a pagamento.

CSRF che consente agli aggressori di disconnettere i siti da Patreon
Versioni interessate: < 1.7.0
ID CVE : CVE-2021-24231
CVSSv3: 6.5
CCSS: 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;
			}
			

Questa è simile all'ultima vulnerabilità in quanto è lo stesso tipo di attacco (CSRF) ma prende di mira gli amministratori. Questo particolare vettore di attacco funziona come il precedente. Un utente malintenzionato deve ottenere un amministratore che ha effettuato l'accesso per visitare un collegamento appositamente predisposto.

Poiché questo specifico endpoint può disconnettere un sito da Patreon, anche gli aggressori che prendono di mira questo vettore di attacco possono fare proprio questo, impedendo la sincronizzazione di nuovi contenuti con il sito.

Sequenza temporale

  • Tentativo di contatto iniziale (non riuscito) – 4 dicembre
  • Secondo tentativo di contatto – 11 dicembre
  • Gli autori prendono atto della relazione – 15 dicembre
  • La versione 1.7.0 viene rilasciata il 5 gennaio
  • Segnaliamo due ulteriori problemi con XSS: il 9 marzo
  • Gli autori riconoscono il secondo rapporto – 9 marzo
  • La versione 1.7.2 viene rilasciata l'11 marzo

Conclusione

Ti consigliamo di controllare la versione corrente del plug-in Patreon-Connect che stai utilizzando sul tuo sito e, se non la 1.7.2, aggiornala il prima possibile!

In Jetpack, lavoriamo sodo per assicurarci che i tuoi siti Web siano protetti da questo tipo di vulnerabilità. Per essere un passo avanti a qualsiasi nuova minaccia, dai un'occhiata a Jetpack Scan, che include la scansione della sicurezza e la rimozione automatizzata del malware.

Crediti

Questa divulgazione di sicurezza è stata resa possibile grazie a George Stephanis, Fioravante Souza, Miguel Neto, Benedict Singer e Marc Montpas.