PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/controller/class-mask-login.php +80 -20 6.0.1 → 6.3.0 View file →
@@ -173,14 +173,10 @@
173 173 * @return void
174 174 * @since 2.8.0
175 175 */
176 176 public function before_mask_login_handle(): void {
177 - // Some plugins for Cron actions clear HTTP_HOST-param.
178 - $host = defender_get_data_from_request( 'HTTP_HOST', 's' );
179 - if ( ! isset( $host['HTTP_HOST'] ) ) {
180 - $host = '';
181 - }
182 - $current_url = set_url_scheme( 'http://' . $host . defender_get_data_from_request( 'REQUEST_URI', 's' ) );
177 + $request_uri = (string) defender_get_data_from_request( 'REQUEST_URI', 's' );
178 + $current_url = home_url( $request_uri );
183 179 $login_url = $this->get_model()->get_new_login_url( $this->get_site_url() );
184 180
185 181 if (
186 182 ! is_user_logged_in() &&
@@ -214,8 +210,11 @@
214 210 // Make sure that wp-login.php is never used in site URLs or redirects.
215 211 if ( ! $this->service->is_login_url() ) {
216 212 $redirect_path = trim( (string) wp_parse_url( $location, PHP_URL_PATH ), '/' );
217 213 if ( $redirect_path === $this->get_model()->mask_url ) {
214 + if ( $this->is_recipient_email_action() ) {
215 + return $location;
216 + }
218 217 $this->maybe_lock();
219 218 }
220 219 }
221 220
@@ -876,8 +875,12 @@
876 875 $action = defender_get_data_from_request( 'action', 'g' );
877 876 $key = wp_unslash( defender_get_data_from_request( 'key', 'r' ) );
878 877 $login = wp_unslash( defender_get_data_from_request( 'login', 'r' ) );
879 878 $wd_ml_token = defender_get_data_from_request( 'wd-ml-token', 'g' );
879 + $cookie_name = 'wd-rp-' . COOKIEHASH;
880 + $rp_path = defined( 'COOKIEPATH' ) ? COOKIEPATH : '/';
881 + $rp_domain = defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '';
882 +
880 883 if (
881 884 isset( $action, $key, $login, $wd_ml_token )
882 885 && 'rp' === $action
883 886 && $login === $wd_ml_token
@@ -884,35 +887,59 @@
884 887 ) {
885 888
886 889 $user = check_password_reset_key( $key, $login );
887 890 if ( ! is_wp_error( $user ) ) {
888 - $value = sprintf( '%s:%s', $login, $key );
889 - set_site_transient( 'wd-rp-' . COOKIEHASH, $value, 2 * MINUTE_IN_SECONDS );
891 + $token = wp_generate_password( 20, false );
892 + $transient_key = 'wd-rp-' . COOKIEHASH . '_' . $token;
893 + $value = sprintf( '%s:%s', $login, $key );
894 +
895 + set_site_transient( $transient_key, $value, 2 * MINUTE_IN_SECONDS );
896 + setcookie( $cookie_name, $token, 0, $rp_path, $rp_domain, is_ssl(), true );
897 + $_COOKIE[ $cookie_name ] = $token;
898 +
890 899 wp_safe_redirect( remove_query_arg( array( 'key', 'login', 'wd-ml-token' ) ) );
891 900 exit;
892 901 }
893 902 }
894 - $value = get_site_transient( 'wd-rp-' . COOKIEHASH );
903 +
904 + $cookie_token = defender_get_data_from_request( $cookie_name, 'c' );
905 + if ( ! is_string( $cookie_token ) || '' === trim( $cookie_token ) ) {
906 + return;
907 + }
908 +
909 + $transient_key = 'wd-rp-' . COOKIEHASH . '_' . $cookie_token;
910 + $value = get_site_transient( $transient_key );
911 +
895 912 // Process the data and display the result.
896 913 if (
897 914 isset( $action )
898 915 && in_array( $action, array( 'rp', 'resetpass' ), true )
899 - && isset( $value ) && 0 < strpos( $value, ':' )
916 + && is_string( $value ) && 0 < strpos( $value, ':' )
900 917 ) {
901 918 [ $login, $key ] = explode( ':', wp_unslash( $value ), 2 );
902 919 $user = check_password_reset_key( $key, $login );
920 +
921 + if ( is_wp_error( $user ) ) {
922 + delete_site_transient( $transient_key );
923 + setcookie( $cookie_name, ' ', time() - YEAR_IN_SECONDS, $rp_path, $rp_domain, is_ssl(), true );
924 + unset( $_COOKIE[ $cookie_name ] );
925 +
926 + return;
927 + }
928 +
903 929 if ( 'resetpass' === $action ) {
904 - delete_site_transient( 'wd-rp-' . COOKIEHASH );
930 + delete_site_transient( $transient_key );
931 + setcookie( $cookie_name, ' ', time() - YEAR_IN_SECONDS, $rp_path, $rp_domain, is_ssl(), true );
932 + unset( $_COOKIE[ $cookie_name ] );
905 933 }
906 - if ( ! is_wp_error( $user ) ) {
907 - $this->render_partial(
908 - 'mask-login/reset',
909 - array(
910 - 'user' => $user,
911 - )
912 - );
913 - exit;
914 - }
934 +
935 + $this->render_partial(
936 + 'mask-login/reset',
937 + array(
938 + 'user' => $user,
939 + )
940 + );
941 + exit;
915 942 }
916 943 }
917 944
918 945 /**
@@ -927,8 +954,12 @@
927 954 // Admin post requests to admin-post.php should be allowed.
928 955 $action = defender_get_data_from_request( 'action', 'r' );
929 956 $allowed = 'wp-admin/admin-post.php' === $path && is_string( $action ) && '' !== trim( $action );
930 957
958 + if ( 'wp-admin/admin-ajax.php' === $path && $this->is_recipient_email_action() ) {
959 + $allowed = true;
960 + }
961 +
931 962 /**
932 963 * Filter to allow whitelisting paths from login masking.
933 964 *
934 965 * @param bool $allowed Is current path allowed?.
@@ -936,8 +967,37 @@
936 967 *
937 968 * @since 2.6.4
938 969 */
939 970 return apply_filters( 'wd_mask_login_is_allowed_path', $allowed, $path );
971 + }
972 +
973 + /**
974 + * Check if the request is a signed recipient email action.
975 + *
976 + * @return bool
977 + */
978 + private function is_recipient_email_action(): bool {
979 + $action = defender_get_data_from_request( 'action', 'r' );
980 + $hash = defender_get_data_from_request( 'hash', 'r' );
981 + if ( ! is_string( $hash ) || '' === trim( $hash ) ) {
982 + return false;
983 + }
984 +
985 + if ( Notification::SLUG_UNSUBSCRIBE === $action ) {
986 + $slug = defender_get_data_from_request( 'slug', 'r' );
987 +
988 + return is_string( $slug ) && '' !== trim( $slug );
989 + }
990 +
991 + if ( Notification::SLUG_SUBSCRIBE !== $action ) {
992 + return false;
993 + }
994 +
995 + $slug = defender_get_data_from_request( 'uid', 'r' );
996 + $slugs = defender_get_data_from_request( 'uids', 'r' );
997 +
998 + return ( is_string( $slug ) && '' !== trim( $slug ) )
999 + || ( is_string( $slugs ) && '' !== trim( $slugs ) );
940 1000 }
941 1001
942 1002 /**
943 1003 * An endpoint for fetching Post/Page.