Unauthenticated Privilege Escalation Vulnerability Patched in Sweet Date Theme

Published 5 December 2024
Table of Contents

This blog post discusses about the findings on the Sweet Date theme. If you’re a Sweet Date user, please update the theme to version 3.8.0 or higher.

All paid Patchstack users are protected from this vulnerability. Sign up for the free Community account first, to scan for vulnerabilities and apply protection for only $5 / site per month with Patchstack.

For plugin developers, we have security audit services and Enterprise API for hosting companies.

About the Sweet Date Theme

The Sweet Date theme (premium version), which has nearly 10,000 sales, is one of the popular premium themes specially designed to be used as a dating theme. It can be customized to match any business domain since it has community capabilities.

The security vulnerabilities

The theme suffers from an unauthenticated privilege escalation vulnerability. As a result, it could have allowed any unauthenticated user to increase their privileges and take over the WordPress site by performing a series of HTTP requests.

This vulnerability occurred because the code that handles user input didn’t have any authorization or nonce check. If registration is enabled on the settings any attacker can takeover the website.

The theme also didn’t check if the user is calling the wp_ajax_fb_intialize action with a $user_ID parameter is actually the owner of that account, allowing anyone to reset the password of any account. Patchstack assigned CVE-2024-43222 to this vulnerability.

The main vulnerability existed in the function wp_ajax_fb_intialize:

function wp_ajax_fb_intialize(){
    @error_reporting( 0 ); // Don't break the JSON result
    header( 'Content-type: application/json' );

    if( !isset( $_REQUEST['FB_response'] ) || !isset( $_REQUEST['FB_userdata'] ))
    die( json_encode( array( 'error' => esc_html__('Authenication required.', 'sweetdate') )));

    $FB_response = $_REQUEST['FB_response'];
    $FB_userdata = $_REQUEST['FB_userdata'];
    $FB_userid = $FB_userdata['id'];

    if( !$FB_userid )
    die( json_encode( array( 'error' => esc_html__('Please connect your facebook account.', 'sweetdate') )));

    global $wpdb;
    //check if we already have matched our facebook account
    $user_ID = $wpdb->get_var( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = '_fbid' AND meta_value = '$FB_userid'" );
    
	
    //if facebook is not connected
    if( !$user_ID ){
        $user_email = $FB_userdata['email'];
        $user_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->users WHERE user_email = '".$wpdb->escape($user_email)."'" );

        $redirect = '';

        //if we have a registered user with this Facebook email
        if(!$user_ID )
        {
            if ( !get_option( 'users_can_register' )) {
                die( json_encode( array( 'error' => esc_html__('Registration is not open at this time. Please come back later.', 'sweetdate') )));
            }
            if (sq_option('facebook_register', 0) == 0) {
                die( json_encode( array( 'error' => esc_html__('Registration using Facebook is not currently allowed. Please use our Register page', 'sweetdate') )));
            }

            extract( $FB_userdata );

            $display_name = $name;

            $user_email = $email;
            if ( empty( $user_email ))
            die( json_encode( array( 'error' => esc_html__('Please re-connect your facebook account as we couldn\'t find your email address.', 'sweetdate') )));

            if( empty( $name ))
            die( json_encode( array( 'error' => 'empty_name', esc_html__('We didn\'t find your name. Please complete your facebook account before proceeding.', 'sweetdate') )));

            $user_login = sanitize_title_with_dashes( sanitize_user( $display_name, true ));

            if ( username_exists( $user_login )) {
                $user_login = $user_login. time();
            }

            $user_pass = wp_generate_password( 12, false );
            $userdata = compact( 'user_login', 'user_email', 'user_pass', 'display_name' );
            $userdata =  apply_filters('kleo_fb_register_data', $userdata);

            $user_ID = wp_insert_user( $userdata );
            if ( is_wp_error( $user_ID ))
            die( json_encode( array( 'error' => $user_ID->get_error_message())));

            //send email with password
            wp_new_user_notification( $user_ID, wp_unslash( $user_pass ) );

            do_action('fb_register_action',$user_ID);

            if( ctype_digit( $id ) ){
                update_user_meta( $user_ID, '_fbid', $id );
                //add Facebook image
                update_user_meta($user_ID, 'kleo_fb_picture', 'https://graph.facebook.com/' . $id . '/picture');
            }

            $logintype = 'register';
            $redirect = apply_filters('kleo_fb_register_redirect',bp_core_get_user_domain( $user_ID ).'profile/edit/group/1/?fb=registered');
        }
        else
        {
            if( ctype_digit( $FB_userdata['id'] ) ){
                update_user_meta( $user_ID, '_fbid', $FB_userdata['id'] );
                //add Facebook image
                update_user_meta($user_ID, 'kleo_fb_picture', 'https://graph.facebook.com/' . $FB_userdata['id'] . '/picture');
            }

            $logintype = 'login';
        }
    }
    else
    {
        $logintype = 'login';
    }

    wp_set_auth_cookie( $user_ID, false, false );
    die( json_encode( array( 'loggedin' => true, 'type' => $logintype, 'url' => $redirect )));
}

The patch

To patch the vulnerability, the vendor stopped taking the e-mail from user input. Instead, the code actually gets it from a logged-in Facebook user object and checks if it is actually connected to the WordPress account. The patched code can be seen below:

Conclusion

Supplying user input to functions like wp_set_auth_cookie(), wp_update_user(), update_user_meta() or other similar functions should only be allowed under strict whitelisting options. Otherwise, the values should be checked and set by the vendor according to the right privilege levels.

If you want to read more about best practices about privilege escalation you can read the Patchstack Academy to stay up to date!

Want to learn more about finding and fixing vulnerabilities?

Explore our Academy to master the art of finding and patching vulnerabilities within the WordPress ecosystem. Dive deep into detailed guides on various vulnerability types, from discovery tactics for researchers to robust fixes for developers. Join us and contribute to our growing knowledge base.

Timeline

22 August, 2024Vulnerability is found and reported to the Vendor.
14 November, 2024The vendor sent the proposed patch for the vulnerabilities to Patchstack.
15 November, 2024We have validated the patch but are unable to confirm if it has been released yet. We reach back to the vendor.
3 December, 2024Published the vulnerability to the Patchstack Vulnerability Database (No confirmation from the vendor regarding the released patched version).
5 December, 2024Security advisory article publicly released.

Help us make the Internet a safer place

Making the WordPress ecosystem more secure is a team effort, and we believe that plugin developers and security researchers should work together.

  • If you’re a plugin developer, join our mVDP program that makes it easier to report, manage and address vulnerabilities in your software.
  • If you’re a security researcher, join Patchstack Alliance to report vulnerabilities & earn rewards.

The latest in Security advisories

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.
crossmenu