From 00e71b304d4c4253611b0a123435d760ffae0330 Mon Sep 17 00:00:00 2001 From: Alex MacArthur Date: Tue, 13 Feb 2018 07:49:47 -0600 Subject: [PATCH 1/4] Hash customer email address in download URLs. --- includes/class-wc-download-handler.php | 22 ++++++++++++++++++++-- includes/class-wc-order-item-product.php | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index b9a7a5decae..37f6665b078 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -21,7 +21,7 @@ class WC_Download_Handler { * Hook in methods. */ public static function init() { - if ( isset( $_GET['download_file'], $_GET['order'], $_GET['email'] ) ) { + if ( isset( $_GET['download_file'], $_GET['order'] ) && ( isset($_GET['email'] ) || isset( $_GET['uid'] ) ) ) { add_action( 'init', array( __CLASS__, 'download_product' ) ); } add_action( 'woocommerce_download_file_redirect', array( __CLASS__, 'download_file_redirect' ), 10, 2 ); @@ -41,8 +41,26 @@ class WC_Download_Handler { self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); } + // Fallback, accept email address if it's passed. + if ( empty($_GET['email'] ) && empty( $_GET['uid'] ) ) { + self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); + } + + if(isset($_GET['email'])) { + $email_address = $_GET['email']; + } else { + // Get email address from order to verify hash. + $order_id = wc_get_order_id_by_order_key($_GET['order']); + $order = new WC_Order($order_id); + $email_address = $order->get_billing_email(); + + if( $_GET['uid'] !== hash('sha256', $email_address) ) { + self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); + } + } + $download_ids = $data_store->get_downloads( array( - 'user_email' => sanitize_email( str_replace( ' ', '+', $_GET['email'] ) ), + 'user_email' => sanitize_email( str_replace( ' ', '+', $email_address ) ), 'order_key' => wc_clean( $_GET['order'] ), 'product_id' => $product_id, 'download_id' => wc_clean( preg_replace( '/\s+/', ' ', $_GET['key'] ) ), diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index e52779327e4..0c8a44e698b 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -383,7 +383,7 @@ class WC_Order_Item_Product extends WC_Order_Item { $files[ $download_id ]['download_url'] = add_query_arg( array( 'download_file' => $product_id, 'order' => $order->get_order_key(), - 'email' => urlencode( $order->get_billing_email() ), + 'uid' => hash('sha256', $order->get_billing_email()), 'key' => $download_id, ), trailingslashit( home_url() ) ); } From 3e0e75ebc30ea82400301556ad329bbe2344e348 Mon Sep 17 00:00:00 2001 From: Alex MacArthur Date: Wed, 14 Feb 2018 07:49:51 -0600 Subject: [PATCH 2/4] Fix spacing issues. --- includes/class-wc-download-handler.php | 12 ++++++------ includes/class-wc-order-item-product.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 37f6665b078..9d19db753cf 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -21,7 +21,7 @@ class WC_Download_Handler { * Hook in methods. */ public static function init() { - if ( isset( $_GET['download_file'], $_GET['order'] ) && ( isset($_GET['email'] ) || isset( $_GET['uid'] ) ) ) { + if ( isset( $_GET['download_file'], $_GET['order'] ) && ( isset( $_GET['email'] ) || isset( $_GET['uid'] ) ) ) { add_action( 'init', array( __CLASS__, 'download_product' ) ); } add_action( 'woocommerce_download_file_redirect', array( __CLASS__, 'download_file_redirect' ), 10, 2 ); @@ -42,19 +42,19 @@ class WC_Download_Handler { } // Fallback, accept email address if it's passed. - if ( empty($_GET['email'] ) && empty( $_GET['uid'] ) ) { + if ( empty( $_GET['email'] ) && empty( $_GET['uid'] ) ) { self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); } - if(isset($_GET['email'])) { + if ( isset( $_GET['email'] ) ) { $email_address = $_GET['email']; } else { // Get email address from order to verify hash. - $order_id = wc_get_order_id_by_order_key($_GET['order']); - $order = new WC_Order($order_id); + $order_id = wc_get_order_id_by_order_key( $_GET['order'] ); + $order = new WC_Order( $order_id ); $email_address = $order->get_billing_email(); - if( $_GET['uid'] !== hash('sha256', $email_address) ) { + if( $_GET['uid'] !== hash( 'sha256', $email_address ) ) { self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); } } diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index 0c8a44e698b..2c851b304bf 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -383,7 +383,7 @@ class WC_Order_Item_Product extends WC_Order_Item { $files[ $download_id ]['download_url'] = add_query_arg( array( 'download_file' => $product_id, 'order' => $order->get_order_key(), - 'uid' => hash('sha256', $order->get_billing_email()), + 'uid' => hash( 'sha256', $order->get_billing_email() ), 'key' => $download_id, ), trailingslashit( home_url() ) ); } From 931bf275118d184974e8b1b8488fceba23e12df5 Mon Sep 17 00:00:00 2001 From: Alex MacArthur Date: Wed, 21 Feb 2018 07:45:07 -0600 Subject: [PATCH 3/4] Fix spacing, use hash_equals to verify uid. --- includes/class-wc-download-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 9d19db753cf..3aadf6b5120 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -54,7 +54,7 @@ class WC_Download_Handler { $order = new WC_Order( $order_id ); $email_address = $order->get_billing_email(); - if( $_GET['uid'] !== hash( 'sha256', $email_address ) ) { + if ( ! hash_equals( $_GET['uid'], hash( 'sha256', $email_address ) ) ) { self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); } } From bc41fb0ba9bd012bcbe3dc98a0513b6242684f49 Mon Sep 17 00:00:00 2001 From: Alex MacArthur Date: Wed, 21 Feb 2018 15:39:43 -0600 Subject: [PATCH 4/4] Use wc_get_order(), handle failure in case WC_Order not returned. --- includes/class-wc-download-handler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-download-handler.php b/includes/class-wc-download-handler.php index 3aadf6b5120..03dbbb5012d 100644 --- a/includes/class-wc-download-handler.php +++ b/includes/class-wc-download-handler.php @@ -51,10 +51,10 @@ class WC_Download_Handler { } else { // Get email address from order to verify hash. $order_id = wc_get_order_id_by_order_key( $_GET['order'] ); - $order = new WC_Order( $order_id ); - $email_address = $order->get_billing_email(); + $order = wc_get_order( $order_id ); + $email_address = is_a( $order, 'WC_Order' ) ? $order->get_billing_email() : null; - if ( ! hash_equals( $_GET['uid'], hash( 'sha256', $email_address ) ) ) { + if ( is_null( $email_address ) || ! hash_equals( $_GET['uid'], hash( 'sha256', $email_address ) ) ) { self::download_error( __( 'Invalid download link.', 'woocommerce' ) ); } }