05 Jul

Authenticated Information Disclosure Vulnerability in Log Emails

Recently we took a quick look over plugins that log emails sent through WordPress. Those emails have the potential to contain sensitive information, so the security of them is important. In two cases we found that the plugin allowed any logged in user to view emails logged by the plugin. In the case of the Log Emails plugin we found that issue went further than the other plugin, as it not only allowed you to view logged emails, but also to view any thing else stored as a post. That includes not only posts, but also pages, and any content that a plugin might store in that way, things like logged emails from this plugin.

The other plugin’s issue was due to making the function that allows viewing logged emails accessible via AJAX and then not checking to insure that the user should be allowed to view it. This plugin issues comes involves a rather obscure action hook admin_action_, which about the only reference we could find to was this StackExchange question. The practical effect is the same as this makes the function available to anyone logged in.

Here is where admin_action_ comes in to play in the file /includes/class.LogEmailsPostTypeLog.php:

38
add_action('admin_action_log_emails_view', array($this, 'viewLog'));

You can see that functions that this causes to run, viewLog(), didn’t do any check on who is doing the request or if they are trying to view a post that was created by the plugin in version 1.0.6 of the plugin:

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
public function viewLog() {
	global $wpdb;
 
	$post_id = empty($_GET['post_id']) ? 0 : absint($_GET['post_id']);
	if (!$post_id) {
		return;
	}
 
	$post = get_post($post_id);
 
	// get next / prev links
	$sql = "
		select ID
		from {$wpdb->posts}
		where ID < {$post->ID} and post_status='publish' and post_type = '" . self::POST_TYPE . "'
		order by ID desc limit 1
	";
	$previous = $wpdb->get_var($sql);
	$previous = $previous ? $this->getLogViewURL($previous) : false;
	$sql = "
		select ID
		from {$wpdb->posts}
		where ID > {$post->ID} and post_status='publish' and post_type = '" . self::POST_TYPE . "'
		order by ID asc limit 1
	";
	$next = $wpdb->get_var($sql);
	$next = $next ? $this->getLogViewURL($next) : false;
 
	// current page and list links
	$current = $this->getLogViewURL($post->ID);
	$list = admin_url('edit.php?post_type=' . self::POST_TYPE);
 
	// actions and filters just for this page
	add_filter('admin_body_class', array($this, 'logViewBodyClass'));
	add_filter('parent_file', array($this, 'fixLogViewMenuHierarchy'));
	add_action('admin_enqueue_scripts', array($this, 'adminEnqueueScripts'));
 
	// show the view
	require_once ABSPATH . 'wp-admin/admin-header.php';
	require LOG_EMAILS_PLUGIN_ROOT . 'views/log-detail.php';
	require ABSPATH . 'wp-admin/admin-footer.php';
}

After we contacted the developer about the issue they released version 1.1.0, which fixes the vulnerability by adding code to the viewLog() function to make sure that the requested post is a logged email and that the user has the ability to edit this type of post (which is defined in another location as a user who has the “activate_plugins capability) before displaying it:

265
266
267
268
269
270
271
272
273
274
275
276
$post_type = get_post_type_object($post->post_type);
 
if ($post->post_type !== self::POST_TYPE) {
	wp_die(__('This post is not an email log.', 'log-emails'));
}
 
if (!current_user_can($post_type->cap->edit_posts)) {
	wp_die(sprintf('<h1>%s</h1><p>%s</p>',
		__('Cheatin&#8217; uh?', 'log-emails'),
		__('You are not allowed to view email logs.', 'log-emails')),
		403);
}

Proof of Concept

The following proof of concept will display the post at ID 1, when submitted while logged in to WordPress.

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

http://[path to WordPress]/wp-admin/admin.php?action=log_emails_view&post_id=1

Timeline

  • 7/1/2016 – Developer notified.
  • 7/2/2016 – Version 1.1.0 released, which fixes vulnerability.

One thought on “Authenticated Information Disclosure Vulnerability in Log Emails

  1. Thanks again for responsible disclosure. I appreciate both that you researched and discovered this vulnerability, and that you gave me a chance to fix it before disclosing it publicly.

    cheers,
    Ross

Leave a Reply

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