From a82b463610de5582ebe84b78267d95a8b780dc69 Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Sat, 21 Sep 2013 06:54:09 +0000 Subject: [PATCH] When using download_url(), if the resource supplies a Content-MD5 header, verify the downloaded file against it. Fixes #20074 Built from https://develop.svn.wordpress.org/trunk@25541 git-svn-id: http://core.svn.wordpress.org/trunk@25461 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/file.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/wp-admin/includes/file.php b/wp-admin/includes/file.php index c731cb8f0a..c53c228467 100644 --- a/wp-admin/includes/file.php +++ b/wp-admin/includes/file.php @@ -485,9 +485,43 @@ function download_url( $url, $timeout = 300 ) { return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); } + $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' ); + if ( $content_md5 ) { + $md5_check = verify_file_md5( $tmpfname, $content_md5 ); + if ( is_wp_error( $md5_check ) ) { + unlink( $tmpfname ); + return $md5_check; + } + } + return $tmpfname; } +/** + * Calculates and compares the MD5 of a file to it's expected value. + * + * @since 3.7.0 + * + * @param string $filename The filename to check the MD5 of. + * @param string $expected_md5 The expected MD5 of the file, either a base64 encoded raw md5, or a hex-encoded md5 + * @return bool|object WP_Error on failure, true on success, false when the MD5 format is unknown/unexpected + */ +function verify_file_md5( $filename, $expected_md5 ) { + if ( 32 == strlen( $expected_md5 ) ) + $expected_raw_md5 = pack( 'H*', $expected_md5 ); + elseif ( 24 == strlen( $expected_md5 ) ) + $expected_raw_md5 = base64_decode( $expected_md5 ); + else + return false; // unknown format + + $file_md5 = md5_file( $filename, true ); + + if ( $file_md5 === $expected_raw_md5 ) + return true; + + return new WP_Error( 'md5_mismatch', sprintf( __( 'The checksum of the file (%1$s) does not match the expected checksum value (%2$s).' ), bin2hex( $file_md5 ), bin2hex( $expected_raw_md5 ) ) ); +} + /** * Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction. * Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present.