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 +86 -40 5.9.0 → 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
@@ -556,21 +554,8 @@
556 554 return new Model_Mask_Login();
557 555 }
558 556
559 557 /**
560 - * Provide data to the frontend via localized script.
561 - *
562 - * @param array $data Data collection is ready to passed.
563 - *
564 - * @return array Modified data array with added this controller data.
565 - */
566 - public function script_data( array $data ): array {
567 - $data['mask_login'] = $this->data_frontend();
568 -
569 - return $data;
570 - }
571 -
572 - /**
573 558 * Redirects the user to the admin URL if the given URL is the home URL.
574 559 *
575 560 * @param string $url The URL to be redirected.
576 561 * @param string $raw_url The raw URL.
@@ -860,24 +845,24 @@
860 845 * @return array An array of strings.
861 846 */
862 847 public function export_strings(): array {
863 848 return array(
864 - $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' ) ),
865 851 );
866 852 }
867 853
868 854 /**
869 - * Generates configuration strings based on the provided configuration and
870 - * whether the product is a pro version.
855 + * Generates configuration strings based on the provided configuration.
871 856 *
872 857 * @param array $config Configuration data.
873 - * @param bool $is_pro Indicates if the product is a pro version.
874 858 *
875 859 * @return array Returns an array of configuration strings.
876 860 */
877 - public function config_strings( array $config, bool $is_pro ): array {
861 + public function config_strings( array $config ): array {
878 862 return array(
879 - $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' ) ),
880 865 );
881 866 }
882 867
883 868 /**
@@ -890,8 +875,12 @@
890 875 $action = defender_get_data_from_request( 'action', 'g' );
891 876 $key = wp_unslash( defender_get_data_from_request( 'key', 'r' ) );
892 877 $login = wp_unslash( defender_get_data_from_request( 'login', 'r' ) );
893 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 +
894 883 if (
895 884 isset( $action, $key, $login, $wd_ml_token )
896 885 && 'rp' === $action
897 886 && $login === $wd_ml_token
@@ -898,35 +887,59 @@
898 887 ) {
899 888
900 889 $user = check_password_reset_key( $key, $login );
901 890 if ( ! is_wp_error( $user ) ) {
902 - $value = sprintf( '%s:%s', $login, $key );
903 - 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 +
904 899 wp_safe_redirect( remove_query_arg( array( 'key', 'login', 'wd-ml-token' ) ) );
905 900 exit;
906 901 }
907 902 }
908 - $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 +
909 912 // Process the data and display the result.
910 913 if (
911 914 isset( $action )
912 915 && in_array( $action, array( 'rp', 'resetpass' ), true )
913 - && isset( $value ) && 0 < strpos( $value, ':' )
916 + && is_string( $value ) && 0 < strpos( $value, ':' )
914 917 ) {
915 918 [ $login, $key ] = explode( ':', wp_unslash( $value ), 2 );
916 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 +
917 929 if ( 'resetpass' === $action ) {
918 - 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 ] );
919 933 }
920 - if ( ! is_wp_error( $user ) ) {
921 - $this->render_partial(
922 - 'mask-login/reset',
923 - array(
924 - 'user' => $user,
925 - )
926 - );
927 - exit;
928 - }
934 +
935 + $this->render_partial(
936 + 'mask-login/reset',
937 + array(
938 + 'user' => $user,
939 + )
940 + );
941 + exit;
929 942 }
930 943 }
931 944
932 945 /**
@@ -941,8 +954,12 @@
941 954 // Admin post requests to admin-post.php should be allowed.
942 955 $action = defender_get_data_from_request( 'action', 'r' );
943 956 $allowed = 'wp-admin/admin-post.php' === $path && is_string( $action ) && '' !== trim( $action );
944 957
958 + if ( 'wp-admin/admin-ajax.php' === $path && $this->is_recipient_email_action() ) {
959 + $allowed = true;
960 + }
961 +
945 962 /**
946 963 * Filter to allow whitelisting paths from login masking.
947 964 *
948 965 * @param bool $allowed Is current path allowed?.
@@ -950,8 +967,37 @@
950 967 *
951 968 * @since 2.6.4
952 969 */
953 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 ) );
954 1000 }
955 1001
956 1002 /**
957 1003 * An endpoint for fetching Post/Page.