28 Jul

False Vulnerability Report: Stored XSS in XCloner

As part of our cataloging the vulnerabilities in WordPress plugins for our service we come across false reports of vulnerabilities from time to time. So that others don’t spend their time looking over these as well, we post our findings on them.

One of the problems in determining if a report of a vulnerability in a plugin is real or not, is that sometimes a developer will make changes to the plugin based on a report even if there is not a vulnerability. In one past case that involved this the developer added duplicative sanitization to a plugin. In the case of a report of a stored XSS (or what we refer to a persistent cross-site scripting (XSS)) vulnerability in the plugin XCloner, the developer added sanitization code that isn’t duplicative, but doesn’t fix a security vulnerability.

In versions prior to 3.1.5 of the plugin, it was possible to insert html tags in settings fields, so that JavaScript code could be added to them and run. Depending on how and who could do that could be a persistent cross-site (XSS) vulnerability. In this case, the advisory indicated that they would be saved on admin page in WordPress. Since the relevant page, is only accessible by Administrator level users, that in itself wouldn’t be a vulnerability since they have they normally unfiltered_html capability, which allows them to do the equivalent of XSS. Since the settings were not intended to be able to output JavaScript code, it could be considered a bug though. There still could be a security vulnerability if the saving of settings is susceptible to cross-site request forgery (CSRF), which causes someone’s web browser to take action on a website that they did not intend.

The proof of concept provided with the report seem to indicate that was the case, seeing as you protect against CSRF with a nonce and there was no nonce include in it:

             <input type="hidden" name="cron_bname" 
             <input type="submit" name="submit">

Looking at the changes made in the version they reported fixed the issue, there was no changes related to a nonce checking, which left open the possibility there was still an unfixed CSRF vulnerability in the plugin.

When we tested out the proof of concept, we found it didn’t work. A quick look at the code showed why, there was in fact the CSRF protection in the function config(), which handles saving the settings:

function config($option)
  global $mosConfig_absolute_path, $_CONFIG, $config_file;
  if (@$_REQUEST['action'] == 'save') {
	  if ( empty($_POST) || !wp_verify_nonce($_POST['csrf'],'save') ){
		print 'Sorry, your nonce did not verify.';

Without a cross-site request forgery (CSRF) vulnerability existing, there wasn’t a vulnerability that had existed in older versions, just a bug.