WordPress core stored XSS

Overview

A stored XSS vulnerability in WordPress allows an user with the posting capability to compromise the website.

Under default configuration, the attack requires a Contributor or Author level account. The attacker would insert specially formatted HTML containing JavaScript on a WordPress page or post. Some special configurations may allow posting or editing page content for unauthenticated users.

The malicious script is executed when an administrator views the page. From this point on the attack could proceed to server-side code execution in the same way as with the other recently published WordPress XSS’s.

Details

The following code demonstrates the vulnerability. It should be entered in a page or posting using the HTML edit mode (instead of the default WYSIWYG):

<a href="[caption code=">]</a><a title=" onmouseover=alert('test')  ">link</a>

WordPress shortcode processing manipulates this into the following form:

<a href="</a><a title=" onmouseover=alert('test')  ">link</a>

A real-world exploit could use a style attribute to create a transparent tag covering the whole browser window to force execution of the onmouseover code.

Vulnerable versions

Versions before 4.2.3 starting from at least 3.0 (released in 2010) are vulnerable.

Vendor response

The bug was corrected on July 23, 2015. It has been patched automatically for most users.

Klikki Oy discovered the bug while investigating another stored XSS vulnerability in November 2014. WordPress security team had requested us to review a patch they developed to address HTML formatting bugs. This was a “final review” four days before the planned release. However, we found a new vulnerability that affected the patched version and reported it to WordPress on the same day. The release that had been planned for the next Monday was cancelled. WordPress acknowledged that they are working to patch the new bug too.

WordPress’s advisory seems to suggest that their security team independently found the same bug on the same day, within 17 hours from sending us the patches for final review.

WordPress didn’t inform us about the upcoming release eight months later. We got no updates about the status of this bug after November 2014.

WordPress didn’t originally credit us for the finding and quietly removed a link to this advisory after it was posted in a comment on WordPress.org. A mention about our bug report was added in their advisory afterwards.

Timeline detailing some of the key points:

  • September 26, 2014: The original WordPress 3 stored XSS reported to WordPress security team by Klikki
  • September 26, 2014: Report acknowledged by WordPress
  • November 6, 2014: WordPress security team mentions discovering related issues dealing with HTML formatting, requiring authentication, while investigating our original report. Sends patches “for your final review”. Release planned for Monday November 10, 2014.
  • November 7, 2014: the second bug (subject of this advisory), not corrected by the final patch, reported to WordPress by Klikki. Suggested a more robust way of HTML formatting to prevent any similar unknown attacks in the future.
  • November 7, 2014: WordPress comment on the suggested solution; “an updated patch” to be expected soon.
  • November 13, 2014: Another patch received for testing
  • November 20, 2014: Public release of both issues planned “preferably before Thanksgiving”
  • November 20, 2014: The original WordPress 3 bug released
  • July 23, 2015: The second bug (subject of this advisory) fixed. WordPress credits “Jon Cave … of WordPress security team” for the finding.
  • July 23, 2015: Over 8 hours later, after a screencap was made public, WordPress changes the wording to include “later reported by Jouko Pynnönen” of Klikki.
  • July 24, 2015: This advisory

Credits

The vulnerability was discovered by Jouko Pynnönen of Klikki Oy, Finland.

Updated 25 July, 2015: added some explanation under “Vendor response”.