Full Disclosure mailing list archives

By Date By Thread WordPress 3 persistent script injection From: Jouko Pynnonen <jouko () iki fi>

Date: Thu, 20 Nov 2014 21:52:14 +0200

OVERVIEW ======== A security flaw in WordPress 3 allows injection of JavaScript into certain text fields. In particular, the problem affects comment boxes on WordPress posts and pages. These don't require authentication by default. The JavaScript injected into a comment is executed when the target user views it, either on a blog post, a page, or in the Comments section of the administrative Dashboard. In the most obvious scenario the attacker leaves a comment containing the JavaScript and some links in order to put the comment in the moderation queue. The exploit is not then visible to normal users, search engines, etc. When a blog administrator goes to the Dashboard/Comments section to review new comments, the JavaScript gets executed. The script can then perform operations with administrator privileges. For instance, our PoC exploits first clean up traces of the injected script from the database, then perform other administrative tasks such as changing the current user's password, adding a new administrator account, or using the plugin editor to write attacker-supplied PHP code on the server (this impact applies to any WordPress XSS if triggered by an administrator). These operations happen in the background without the user seeing anything out of ordinary. If the attacker writes new PHP code on the server via the plugin editor, another AJAX request can be used to execute it instantaneously, whereby the attacker gains operating system level access on the server. The exploit will NOT be triggered directly at the Dashboard "root view" because only snippets (20 first words) of the latest comments are shown there with all HTML stripped. If approved there, the exploit will be triggered by any user viewing the targeted blog posting or page, with their corresponding privileges. Plugins that let unprivileged users to enter HTML text may offer other attack vectors. DETAILS ======= WordPress allows a few HTML tags in comments, such as the anchor <A>, bold <B>, and code <CODE> tags. Certain white-listed attributes are allowed in each tag. Obviously, the "href" attribute is important for anchor tags, but e.g. the "onmouseover" attribute would be undesirable. The problem occurs in a text formatting function called wptexturize() which is normally executed for each comment and other blocks of text. The function replaces certain simple characters with fancier HTML entities. For instance, straight quote symbols are replaced with opening and closing curly quotes, unicode 8220 and 8221. In order to avoid interfering with HTML formatting, wptexturize() first splits the text in segments. The splitting is expected to pick HTML tags (which aren't texturized) apart from running text (which is texturized). In addition to HTML tags, the code is supposed to recognize square-bracketed shortcodes such as [CODE] and avoid texturizing them. The splitting is implemented with a regular expression in wp-includes/formatting.php: $textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE); A text containing carefully mixed square and angle brackets confuses the splitting process and results in HTML code getting partially texturized. An attacker can exploit the bug to supply any attributes in the allowed HTML tags. A style attribute can be used to create a transparent tag covering the whole window, forcing the execution of its onmouseover handler. In practical applications the script would probably first remove the transparent tag to avoid interfering with UI events and re-triggering the handler. It could then insert a new <SCRIPT> tag to load a more complex JavaScript file to execute from another web server. This script can use e.g. jQuery to chain AJAX operations for posting HTML forms and retrieving the required nonces. AFFECTED VERSIONS ================= We tested a few WordPress versions from 3.0 to the latest 3.9.2. All tested versions were vulnerable. The problem seems to have gone uncorrected for almost four years. Version 4.0 uses a different kind of regular expression and is NOT vulnerable to this problem. WORKAROUNDS =========== Texturizing can be easily disabled by adding a return statement in the beginning of the function in wp-includes/formatting.php: function wptexturize($text) { return $text; // ADD THIS LINE global $wp_cockneyreplace; This changes how some punctuation marks look like but the difference is quite minor. We have also made a WordPress plugin available for disabling texturization. For more information and an up-to-date version of this document, please refer to our website http://klikki.fi The preferred solution should be applying the official patch released by WordPress. VENDOR RESPONSE =============== WordPress was notified on September 26 and has released patches correcting the problem. The WordPress security advisory is available at https://wordpress.org/news/2014/11/wordpress-4-0-1/ CREDITS ======= The vulnerability was discovered and researched by Jouko Pynnonen, Klikki Oy, Finland. -- Jouko Pynnonen <jouko () iki fi> Klikki Oy - http://klikki.fi _______________________________________________ Sent through the Full Disclosure mailing list http://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: http://seclists.org/fulldisclosure/ By Date By Thread Current thread: WordPress 3 persistent script injection Jouko Pynnonen (Nov 20)