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 +93 -44 5.8.1 → 6.3.0 View file →
@@ -57,9 +57,8 @@
57 57 /**
58 58 * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
59 59 */
60 60 public function __construct() {
61 - add_filter( 'wp_defender_advanced_tools_data', array( $this, 'script_data' ) );
62 61 // Internal cache, so we don't need to query many times.
63 62 $this->model = wd_di()->get( Model_Mask_Login::class );
64 63 $this->service = wd_di()->get( Component_Mask_Login::class );
65 64 $this->register_routes();
@@ -174,14 +173,10 @@
174 173 * @return void
175 174 * @since 2.8.0
176 175 */
177 176 public function before_mask_login_handle(): void {
178 - // Some plugins for Cron actions clear HTTP_HOST-param.
179 - $host = defender_get_data_from_request( 'HTTP_HOST', 's' );
180 - if ( ! isset( $host['HTTP_HOST'] ) ) {
181 - $host = '';
182 - }
183 - $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 );
184 179 $login_url = $this->get_model()->get_new_login_url( $this->get_site_url() );
185 180
186 181 if (
187 182 ! is_user_logged_in() &&
@@ -215,8 +210,11 @@
215 210 // Make sure that wp-login.php is never used in site URLs or redirects.
216 211 if ( ! $this->service->is_login_url() ) {
217 212 $redirect_path = trim( (string) wp_parse_url( $location, PHP_URL_PATH ), '/' );
218 213 if ( $redirect_path === $this->get_model()->mask_url ) {
214 + if ( $this->is_recipient_email_action() ) {
215 + return $location;
216 + }
219 217 $this->maybe_lock();
220 218 }
221 219 }
222 220
@@ -252,9 +250,10 @@
252 250 }
253 251
254 252 if ( '/' . ltrim( $this->get_model()->mask_url, '/' ) === $requested_path ) {
255 253 // We need to redirect this one to wp-login and open it.
256 - return $this->show_login_page();
254 + $this->show_login_page();
255 + return;
257 256 }
258 257 /**
259 258 * Allowed if:
260 259 * it's AJAX,
@@ -292,9 +291,10 @@
292 291 }
293 292
294 293 // If current is same then we show the login screen.
295 294 if ( $this->service->is_land_on_masked_url( $this->model->mask_url ) ) {
296 - return $this->show_login_page();
295 + $this->show_login_page();
296 + return;
297 297 }
298 298
299 299 // If it's the verification link to change Network Admin Email.
300 300 $is_multisite = is_multisite();
@@ -320,9 +320,10 @@
320 320 ( ! $is_multisite && 'wp-signup.php' === $requested_path_without_slash )
321 321 || $this->service->is_on_login_page( $requested_path_without_slash )
322 322 ) {
323 323 // If they are here and the flow getting here, then just lock.
324 - return $this->maybe_lock();
324 + $this->maybe_lock();
325 + return;
325 326 }
326 327 }
327 328
328 329 /**
@@ -531,9 +532,9 @@
531 532 * Show the forbidden screen.
532 533 */
533 534 public function show_forbidden_screen(): void {
534 535 wp_die(
535 - esc_html__( 'This feature is forbidden temporarily for security reason. Try login again.', 'defender-security' ),
536 + esc_html__( 'This feature is temporarily forbidden for security reasons. Try logging in again.', 'defender-security' ),
536 537 esc_html__( 'Forbidden', 'defender-security' ),
537 538 array(
538 539 'response' => 403,
539 540 )
@@ -553,21 +554,8 @@
553 554 return new Model_Mask_Login();
554 555 }
555 556
556 557 /**
557 - * Provide data to the frontend via localized script.
558 - *
559 - * @param array $data Data collection is ready to passed.
560 - *
561 - * @return array Modified data array with added this controller data.
562 - */
563 - public function script_data( array $data ): array {
564 - $data['mask_login'] = $this->data_frontend();
565 -
566 - return $data;
567 - }
568 -
569 - /**
570 558 * Redirects the user to the admin URL if the given URL is the home URL.
571 559 *
572 560 * @param string $url The URL to be redirected.
573 561 * @param string $raw_url The raw URL.
@@ -857,24 +845,24 @@
857 845 * @return array An array of strings.
858 846 */
859 847 public function export_strings(): array {
860 848 return array(
861 - $this->get_model()->is_active() ? esc_html__( 'Active', 'defender-security' ) : esc_html__( 'Inactive', 'defender-security' ),
849 + \WP_Defender\Model\Setting\Mask_Login::get_module_name() . ' '
850 + . ( $this->get_model()->enabled ? esc_html__( 'active', 'defender-security' ) : esc_html__( 'inactive', 'defender-security' ) ),
862 851 );
863 852 }
864 853
865 854 /**
866 - * Generates configuration strings based on the provided configuration and
867 - * whether the product is a pro version.
855 + * Generates configuration strings based on the provided configuration.
868 856 *
869 857 * @param array $config Configuration data.
870 - * @param bool $is_pro Indicates if the product is a pro version.
871 858 *
872 859 * @return array Returns an array of configuration strings.
873 860 */
874 - public function config_strings( array $config, bool $is_pro ): array {
861 + public function config_strings( array $config ): array {
875 862 return array(
876 - $config['enabled'] ? esc_html__( 'Active', 'defender-security' ) : esc_html__( 'Inactive', 'defender-security' ),
863 + \WP_Defender\Model\Setting\Mask_Login::get_module_name() . ' '
864 + . ( $config['enabled'] ? esc_html__( 'active', 'defender-security' ) : esc_html__( 'inactive', 'defender-security' ) ),
877 865 );
878 866 }
879 867
880 868 /**
@@ -887,8 +875,12 @@
887 875 $action = defender_get_data_from_request( 'action', 'g' );
888 876 $key = wp_unslash( defender_get_data_from_request( 'key', 'r' ) );
889 877 $login = wp_unslash( defender_get_data_from_request( 'login', 'r' ) );
890 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 +
891 883 if (
892 884 isset( $action, $key, $login, $wd_ml_token )
893 885 && 'rp' === $action
894 886 && $login === $wd_ml_token
@@ -895,35 +887,59 @@
895 887 ) {
896 888
897 889 $user = check_password_reset_key( $key, $login );
898 890 if ( ! is_wp_error( $user ) ) {
899 - $value = sprintf( '%s:%s', $login, $key );
900 - 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 +
901 899 wp_safe_redirect( remove_query_arg( array( 'key', 'login', 'wd-ml-token' ) ) );
902 900 exit;
903 901 }
904 902 }
905 - $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 +
906 912 // Process the data and display the result.
907 913 if (
908 914 isset( $action )
909 915 && in_array( $action, array( 'rp', 'resetpass' ), true )
910 - && isset( $value ) && 0 < strpos( $value, ':' )
916 + && is_string( $value ) && 0 < strpos( $value, ':' )
911 917 ) {
912 918 [ $login, $key ] = explode( ':', wp_unslash( $value ), 2 );
913 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 +
914 929 if ( 'resetpass' === $action ) {
915 - 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 ] );
916 933 }
917 - if ( ! is_wp_error( $user ) ) {
918 - $this->render_partial(
919 - 'mask-login/reset',
920 - array(
921 - 'user' => $user,
922 - )
923 - );
924 - exit;
925 - }
934 +
935 + $this->render_partial(
936 + 'mask-login/reset',
937 + array(
938 + 'user' => $user,
939 + )
940 + );
941 + exit;
926 942 }
927 943 }
928 944
929 945 /**
@@ -938,8 +954,12 @@
938 954 // Admin post requests to admin-post.php should be allowed.
939 955 $action = defender_get_data_from_request( 'action', 'r' );
940 956 $allowed = 'wp-admin/admin-post.php' === $path && is_string( $action ) && '' !== trim( $action );
941 957
958 + if ( 'wp-admin/admin-ajax.php' === $path && $this->is_recipient_email_action() ) {
959 + $allowed = true;
960 + }
961 +
942 962 /**
943 963 * Filter to allow whitelisting paths from login masking.
944 964 *
945 965 * @param bool $allowed Is current path allowed?.
@@ -947,8 +967,37 @@
947 967 *
948 968 * @since 2.6.4
949 969 */
950 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 ) );
951 1000 }
952 1001
953 1002 /**
954 1003 * An endpoint for fetching Post/Page.