Plugin Directory

Changeset 3410794


Ignore:
Timestamp:
12/04/2025 11:28:25 AM (9 days ago)
Author:
ignatggeorgiev
Message:

Bump to 1.5.8

Location:
sg-security/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • sg-security/trunk/core/Activity_Log/Activity_Log.php

    r3149177 r3410794  
    178178            1 === Helper_Service::is_cron_disabled()
    179179        ) {
     180            if ( ! current_user_can( 'manage_options' ) ) {
     181                wp_die(
     182                    esc_html__( 'You don’t have access to this page. Please contact the administrator of this website for further assistance.', 'sg-security' ),
     183                    esc_html__( 'Restricted access', 'sg-security' ),
     184                    array(
     185                        'sgs_error' => true,
     186                        'response'  => 403,
     187                    )
     188                );
     189            }
     190
    180191            $this->delete_old_activity_logs();
    181192        }
  • sg-security/trunk/core/Custom_Login_Url/Custom_Login_Url.php

    r3165493 r3410794  
    2525     */
    2626    private $options = array();
     27
     28    /**
     29     * Flag for the ultimate-member plugin forms.
     30     *
     31     * @var boolean
     32     */
     33    private $um_form_detected_error = false;
    2734
    2835    /**
     
    4148
    4249    /**
    43      * Change the site url to include the custom login url token,
     50     * Change the site URL to include the custom login URL token,
    4451     *
    4552     * @param string $url  The URL to be filtered.
     
    5461        $path = Helper::get_url_path( $path ); //phpcs:ignore
    5562
    56         preg_match( '~^(.*)\/(wp-login.php)(?:.*)?[\?|&]action=(.*?)(?:\?|&|$)~', $path, $matches );
    57 
    58         if ( empty( $matches[2] ) ) {
     63        if ( strpos( $path, 'wp-login.php' ) === false ) {
    5964            return $url;
    6065        }
    6166
    62         if ( empty( $matches[3] ) ) {
    63             return $url;
    64         }
    65 
    66         switch ( $matches[3] ) {
    67             case 'postpass':
    68                 return $url;
    69             case 'register':
    70                 $token = 'register';
    71                 break;
    72             case 'rp':
    73                 $token = 'login';
    74                 return $url;
    75         }
    76 
    77         // Add the token to the url if not empty.
     67        if ( preg_match( '~[\?&]action=([^&]*)~', $path, $matches ) ) {
     68            switch ( $matches[1] ) {
     69                case 'postpass':
     70                    return $url;
     71                case 'register':
     72                    $token = 'register';
     73                    break;
     74                case 'rp':
     75                    return $url;
     76            }
     77        } else if (
     78            isset( $_GET[ $this->token ] ) &&
     79            $_GET[ $this->token ] === $this->options['new_slug']
     80        ) {
     81            $token = $this->options['new_slug'];
     82        }
     83
     84        // Add the token to the URL if not empty.
    7885        if ( empty( $token ) ) {
    7986            return $url;
    8087        }
    8188
    82         // Return the url.
     89        // Return the URL.
    8390        return add_query_arg( $this->token, urlencode( $token ), $url );
    8491    }
     
    103110     */
    104111    public function handle_request() {
     112
    105113        // Get the path.
    106114        $path = Helper::get_url_path( $_SERVER['REQUEST_URI'] ); //phpcs:ignore
     
    110118        }
    111119
     120        // Check if we are redirected to the login page, by the LogIn button on the registration page.
     121        if (
     122            $this->is_valid( 'login' ) &&
     123            isset( $_SERVER['HTTP_REFERER'] ) &&
     124            false !== strpos( $_SERVER['HTTP_REFERER'], 'register' ) &&
     125            false !== strpos( $path, 'wp-login.php' )
     126        ) {
     127            $this->redirect_with_token( 'login', 'wp-login.php' );
     128        }
     129
     130        // Check if we are redirected to the registration page, by the Register button on the login page.
     131        if (
     132            $this->is_valid( 'login' ) &&
     133            isset( $_SERVER['HTTP_REFERER'] ) &&
     134            false !== strpos( $_SERVER['HTTP_REFERER'], $this->options['new_slug'] ) &&
     135            isset( $_GET['action'] ) && 'register' === $_GET['action']
     136        ) {
     137            $this->handle_registration();
     138        }
     139
    112140        if ( false !== strpos( $path, 'wp-login' ) || false !== strpos( $path, 'wp-login.php' ) ) {
    113141            $this->handle_login();
     
    117145            $this->handle_registration();
    118146        }
    119 
    120147    }
    121148
     
    139166
    140167    /**
    141      * Adds a token and redirect to the url.
     168     * Adds a token and redirect to the URL.
    142169     *
    143170     * @since  1.1.0
     
    155182
    156183        $url = add_query_arg( $query_vars, site_url( $path ) );
     184
     185        // Get the current URL.
     186        $current_url = ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
     187
     188        // Prevent redirect loop by checking if the current URL matches the redirect URL.
     189        if ( true === $this->compare_urls( $url, $current_url ) ) {
     190            return;
     191        }
    157192
    158193        wp_redirect( $url );
     
    196231
    197232        if ( 'jetpack-sso' === $action && has_filter( 'login_form_jetpack-sso' ) ) {
    198             // Jetpack's SSO redirects from wordpress.com to wp-login.php on the site. Only allow this process to
     233            // Jetpack's SSO redirects from WordPress.com to wp-login.php on the site. Only allow this process to
    199234            // continue if they successfully log in, which should happen by login_init in Jetpack which happens just
    200235            // before this action fires.
     
    293328
    294329    /**
    295      * Handle regostration request.
     330     * Handle registration request.
    296331     *
    297332     * @since  1.1.0
     
    344379     */
    345380    public function show_notices() {
    346         // Bail if we shold not show the notice.
     381        // Bail if we should not show the notice.
    347382        if ( empty( get_option( 'sg_security_show_signup_notice', false ) ) ) {
    348383            return;
     
    391426
    392427    /**
    393      * Adds the login token to the confirmation url.
     428     * Adds the login token to the confirmation URL.
    394429     *
    395430     * @since  1.1.1
     
    409444        }
    410445
    411         // Add the login token to the GDPR confirmation url.
     446        // Add the login token to the GDPR confirmation URL.
    412447        $confirm_url = add_query_arg(
    413448            $this->token,
     
    451486     * @since 1.3.3
    452487     *
    453      * @param  \WP_User $user      \WP_User object of the user that is trying to login.
     488     * @param  \WP_User |\WP_Error $user      \WP_User object of the user that is trying to login or \WP_Error object if a previous callback failed * authentication.
    454489     * @return \WP_Error|\WP_User  If successful, the original \WP_User object, otherwise a \WP_Error object.
    455490     */
    456491    public function maybe_block_custom_login( $user ) {
    457         // Check if the referer slug is set.
     492        // Check if the referrer slug is set.
    458493        if ( ! isset( $_SERVER['HTTP_REFERER'] ) ) {
     494            return $user;
     495        }
     496
     497        // Check if $user is a WP_Error object.
     498        if ( is_wp_error( $user ) ) {
     499            return $user;
     500        }
     501
     502        // Check if the ultimate member plugin form has errors.
     503        if ( true === $this->um_form_detected_error ) {
    459504            return $user;
    460505        }
     
    470515        }
    471516
    472         // Get referer parts by parsing its url.
     517        // Get referrer parts by parsing its URL.
    473518        $referer = str_replace(
    474519            array( home_url(), '/' ),
     
    500545        return $error;
    501546    }
     547
     548    /**
     549     * Adds our 'maybe_block_custom_login' error message, in the Ultimate Member plugin's errors filter.
     550     *
     551     * @param $err_codes Custom error codes array on the ultimate members plugin forms.
     552     *
     553     * @return $err_codes The updated error codes array.
     554     */
     555    public function add_um_form_error_code( $err_codes ) {
     556        // Adds our error message code.
     557        $err_codes[] = 'authentication_failed';
     558
     559        return $err_codes;
     560    }
     561
     562    /**
     563     * Sets the flag, if the ultimate member plugin find error on their forms.
     564     *
     565     * @param  $error The error message.
     566     *
     567     * @param  $key The error code.
     568     *
     569     * @return $error The error message.
     570     */
     571    public function set_um_form_flag( $error, $key ) {
     572        // Check if the UM form has detected and error.
     573        if ( $key ) {
     574            $this->um_form_detected_error = true;
     575        }
     576
     577        return $error;
     578    }
     579
     580    /**
     581     * Adds the 'sgs-token' query string after language change.
     582     */
     583    public function add_sgs_token_to_language_switcher() {
     584        // Check if the language of the login/register pages is getting changed.
     585        if (
     586            $this->is_valid( 'login' ) &&
     587            isset( $_SERVER['HTTP_REFERER'] ) &&
     588            (
     589                false !== strpos( $_SERVER['HTTP_REFERER'], $this->options['new_slug'] ) ||
     590                false !== strpos( $_SERVER['HTTP_REFERER'], $this->options['register'] )
     591            ) &&
     592            isset( $_GET['wp_lang'] )
     593        ) {
     594
     595            // Get the current URL.
     596            $current_url = ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
     597
     598            $parsed_url = wp_parse_url( $current_url );
     599
     600            // Extract query parameters from the URL.
     601            $query_params = array();
     602            if ( isset( $parsed_url['query'] ) ) {
     603                parse_str( $parsed_url['query'], $query_params );
     604            }
     605
     606            // Determine which SGS token to add. Preset it to 'register'.
     607            $query_params['sgs-token'] = $this->options['register'];
     608
     609            if ( false !== strpos( $_SERVER['HTTP_REFERER'], $this->options['new_slug'] ) ) {
     610                $query_params['sgs-token'] = $this->options['new_slug'];
     611            }
     612
     613            // Sanitize all query parameters.
     614            foreach ( $query_params as $key => $value ) {
     615                $query_params[ $key ] = sanitize_text_field( $value );
     616            }
     617
     618            // Build the URL with all the parameters.
     619            $redirect_url = add_query_arg( $query_params, site_url( 'wp-login.php' ) );
     620
     621            // Prevent redirect loop by checking if the current URL matches the redirect URL.
     622            if ( true === $this->compare_urls( $current_url, $redirect_url ) ) {
     623                return;
     624            }
     625
     626            wp_safe_redirect( $redirect_url );
     627            exit;
     628        }
     629    }
     630
     631    /**
     632     * Compare two URLs if they are basically the same.
     633     *
     634     * @param $current_url First URL to compare.
     635     *
     636     * @param $redirect_url Second URL to compare.
     637     *
     638     * @return boolean True if the URLs are the same. False if they are different.
     639     */
     640    public function compare_urls( $current_url, $redirect_url ) {
     641        // Parse the URLs
     642        $current_url = parse_url( $current_url );
     643        $redirect_url = parse_url( $redirect_url );
     644
     645        // Check if both URLs have the same domain.
     646        if ( $current_url['host'] !== $redirect_url['host'] ) {
     647            return false;
     648        }
     649
     650        // Ensure both URLs include "wp-login.php" in the path.
     651        if ( false === strpos( $current_url['path'], 'wp-login.php' ) || false === strpos( $redirect_url['path'], 'wp-login.php' ) ) {
     652            return false;
     653        }
     654
     655        // Parse query strings into arrays for comparison.
     656        parse_str( $current_url['query'], $current_url_params );
     657        parse_str( $redirect_url['query'], $redirect_url_params );
     658
     659        // Compare the total number of query parameters.
     660        if ( count( $current_url_params ) !== count( $redirect_url_params ) ) {
     661            return false;
     662        }
     663
     664        // If a key is missing or a value is different, URLs are not equal.
     665        foreach ( $current_url_params as $query_key => $query_value ) {
     666            if (
     667                    ! array_key_exists( $query_key, $redirect_url_params ) ||
     668                    $redirect_url_params[ $query_key ] !== $query_value
     669                ) {
     670                return false;
     671            }
     672        }
     673
     674        return true;
     675    }
    502676}
  • sg-security/trunk/core/Loader/Loader.php

    r3142129 r3410794  
    292292        add_filter( 'wpdiscuz_login_link', array( $this->custom_login_url, 'custom_login_for_wpdiscuz' ) );
    293293        add_action( 'wp_authenticate_user', array( $this->custom_login_url, 'maybe_block_custom_login' ) );
     294        add_action( 'login_init', array( $this->custom_login_url, 'add_sgs_token_to_language_switcher' ) );
     295        add_filter( 'um_custom_authenticate_error_codes', array( $this->custom_login_url, 'add_um_form_error_code' ) );
     296        add_filter( 'um_submit_form_error', array( $this->custom_login_url, 'set_um_form_flag' ), 100, 2 );
    294297    }
    295298
  • sg-security/trunk/core/Login_Service/Login_Service.php

    r2904929 r3410794  
    4242     */
    4343    public function restrict_login_to_ips() {
     44        // Bail if the user is trying to access password protected page.
     45        if ( isset( $_POST['post_password'] ) && ! is_admin() ) { //phpcs:ignore
     46            return true;
     47        }
     48
    4449        // Get the list of allowed IP addresses.
    4550        $allowed_ips = get_option( 'sg_login_access', array() );
  • sg-security/trunk/readme.txt

    r3273083 r3410794  
    33Tags: security, firewall, malware scanner, web application firewall, login
    44Requires at least: 4.7
    5 Tested up to: 6.8
     5Tested up to: 6.9
    66Requires PHP: 7.0
    7 Stable tag: 1.5.7
     7Stable tag: 1.5.8
    88License: GPLv3
    99License URI: http://www.gnu.org/licenses/gpl-3.0.html
     
    144144
    145145== Changelog ==
     146= Version 1.5.8 =
     147Release Date Dec 4th, 2025
     148
     149* Custom Login improvements
     150* Login Security improvements
     151* Security improvements
     152
    146153= Version 1.5.7 =
    147154Release Date Nov 21st, 2024
  • sg-security/trunk/sg-security.php

    r3194231 r3410794  
    1111 * Plugin URI:        https://siteground.com
    1212 * Description:       Security Optimizer by SiteGround is the all-in-one security solution for your WordPress website. With the carefully selected and easy to configure functions the plugin provides everything you need to secure your website and prevent a number of threats such as brute-force attacks, compromised login, data leaks and more.
    13  * Version:           1.5.7
     13 * Version:           1.5.8
    1414 * Author:            SiteGround
    1515 * Author URI:        https://www.siteground.com
     
    3333// Define version constant.
    3434if ( ! defined( __NAMESPACE__ . '\VERSION' ) ) {
    35     define( __NAMESPACE__ . '\VERSION', '1.5.7' );
     35    define( __NAMESPACE__ . '\VERSION', '1.5.8' );
    3636}
    3737
Note: See TracChangeset for help on using the changeset viewer.