Reflected Cross-Site Scripting (XSS) Vulnerability in Smart Forms
Earlier today we detailed a failed attempt to fix a reflected cross-site scripting (XSS) vulnerability in the latest version of Smart Forms. When putting together a post detailing a vulnerability discovered by others, we check to see if that vulnerability is something that would have been caught by our Plugin Security Checker, an automated tool anyone can use to check to see if a WordPress plugin possibly contains security issues, so that we can continue to improve that tool. With this plugin we found the code that was attempted to be fixed was flagged by the tool and an additional line of code that wasn’t changed in the latest version of the plugin was also flagged. Further checking confirmed that additional line was also vulnerable.
Due to the moderators of the WordPress Support Forum’s continued inappropriate behavior we are full disclosing vulnerabilities in protest until WordPress gets that situation cleaned up, so we are releasing this post and then only trying to notify the developer through the WordPress Support Forum. You can notify the developer of this issue on the forum as well. Hopefully the moderators will finally see the light and clean up their act soon, so these full disclosures will no longer be needed (we hope they end soon). You would think they would have already done that since a previously full disclosed vulnerability was quickly on hackers’ radar, but it appears those moderators have such disdain for the rest of the WordPress community that their continued ability to act inappropriate is more important that what is best for the rest of the community.
Technical Details
The line of code flagged by the Plugin Security Checker is the following:
59 | <form style="display: inline; margin-left:10px;" id="sfFileUploadForm" method="post" enctype="multipart/form-data" target="_self" action="?page=<?php echo $_REQUEST['page'] ?>&action=upload"> |
That will output the value of the GET or POST input “page” without escaping it and would likely lead to a reflected XSS vulnerability unless other code that blocked that from happening ran before that.
Looking the surrounding code we found that code will run when visiting the plugin’s main admin page, /wp-admin/admin.php?page=smart_forms_menu. Since the GET version of “page” is set to something that couldn’t lead to XSS in that URL that limits that from being used to cause XSS. But you can send separate values for the GET and POST version of it, so you could also send the POST version with malicious JavaScript code and under normal settings that will be treated as the value of the REQUEST version of it instead of the GET version.
No code that runs before that line of code stops that, as can be seen with the proof of concept below.
Proof of Concept
The following proof of concept will cause any available cookies to be shown in alert box, when logged in as an Administrator. Major web browsers other than Firefox provide XSS filtering, so this proof of concept will not work in those web browsers.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin.php?page=smart_forms_menu" method="POST"> <input type="hidden" name="page" value='"><script>alert(document.cookie);</script>' /> <input type="submit" value="Submit" /> </form> </body> </html>