Details of an Additional File Deletion Vulnerability – Patched in WordPress 4.9.7

Today WordPress released version 4.9.7, a security release which addresses two separate arbitrary file deletion vulnerabilities requiring Author privileges. Some details can be found on the WordPress.org blog.

The first arbitrary file deletion vulnerability was disclosed June 26, 2018 on the RIPS Tech blog with no official patch to WordPress in place. We released a firewall rule the same day to protect Wordfence users from attacks against this vulnerability.

A Second Vulnerability Discovered

After developing a proof of concept of the attack to aid in writing the Wordfence firewall rule, we decided to have a closer look at the code used to create and delete attachments. During this review, we discovered a second arbitrary file deletion vulnerability exploitable by authors. We released a Wordfence firewall rule to our Premium customers on July 2nd to protect against this vulnerability.

The details of the second vulnerability are as follows: In WordPress core, there is an “upload-attachment” AJAX action used by the media uploader. The AJAX call will handle the file upload and pass an array of additional data about the attachment to wp_insert_post, since media attachments are a specific post type within WordPress.

function wp_ajax_upload_attachment() {
    
    ...
    
    // Post data from user input.
	$post_data = isset( $_REQUEST['post_data'] ) ? $_REQUEST['post_data'] : array();

	// If the context is custom header or background, make sure the uploaded file is an image.
	if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ) ) ) {
		$wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
        
        ...
        
	}

	$attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data );

The vulnerability lies in the way wp_insert_post populates the meta data for the attachment. The path to the attachment file is stored in the meta key _wp_attached_file. By supplying post_data[meta_input][_wp_attached_file] in the request to the “upload-attachment” AJAX action, we can pass in ../../wp-config.php which WordPress will treat as the attachment file.

Similar to the first arbitrary file deletion vulnerability, when an author deletes this attachment, the wp-config.php is deleted allowing the author to go through the initial WordPress installation process which allows them to fully compromise the site.

WordPress Releases a Fix in 4.9.7

The WordPress security team has just released version 4.9.7 which addresses both of these issues by performing some additional checks before deleting attachment files. Specifically, they have added the function wp_delete_file_from_directory which they use to verify the file is within the uploads directory before deleting it.

/**
 * Deletes a file if its path is within the given directory.
 *
 * @since 4.9.7
 *
 * @param string $file      Absolute path to the file to delete.
 * @param string $directory Absolute path to a directory.
 * @return bool True on success, false on failure.
 */
function wp_delete_file_from_directory( $file, $directory ) {
	$real_file = realpath( wp_normalize_path( $file ) );
	$real_directory = realpath( wp_normalize_path( $directory ) );

	if ( false === $real_file || false === $real_directory || strpos( wp_normalize_path( $real_file ), trailingslashit( wp_normalize_path( $real_directory ) ) ) !== 0 ) {
		return false;
	}

	wp_delete_file( $file );

	return true;
}

Timeline

  • 2018-06-29 11:26 AM (-500) – Initial report of second arbitrary file deletion vulnerability submitted to WordPress security team.
  • 2018-07-02 1:14 PM (-500) – Firewall rule released to Wordfence Premium customers to address second vulnerability.
  • 2018-07-05 12:00 PM (-500) – WordPress releases version 4.9.7 which fixes both vulnerabilities.

What To Do

We strongly encourage you to update to 4.9.7 as soon as possible. If you have automatic updates enabled, your site should update within the next 24 hours. Automatic updates are enabled by default in WordPress for minor releases.

Credits: Congrats to Matt Barry, our lead developer at Wordfence for finding this vulnerability and writing up technical details. Thanks to Mikey Veenstra for editing this post. As always, thanks to the WordPress security team for being super responsive and for their hard work helping secure WordPress core.

Did you enjoy this post? Share it!

Comments

4 Comments
  • Does the "temporary hotfix" at
    https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/#temporary-hotfix
    protect against this second vuln, do you think?

  • You guys rock. It is for this exact reason I have recommended to all my clients now to upgrade Wordfence to prem. One client was getting smashed for over 24 hrs last week by a coordinated login attack but Wordfence handled it like a champ. We just sat back and watched until they gave up and moved on. :-)

    • That's awesome feedback Steve. Thanks.

  • Ditto to Steve's comment! You guys rock!