
K Elements
Privilege Escalation
This blog post is about the K Elements plugin vulnerability. If you’re a KLEO theme user who is using the K Elements plugin, please update the plugin to at least version 5.4.0.
If you are a Patchstack customer, you are protected from this vulnerability already, and no further action is required from you.
For plugin developers, we have security audit services and Enterprise API for hosting companies.
About the KLEO Theme
The theme KLEO which has over 23,000 sales, is one of the popular BudyPress-related premium plugins in the WordPress ecosystem. One of the required plugins that are bundled on the theme is the K Elements plugin which is a plugin that provides custom elements and shortcodes. The theme and plugin is developed by SeventhQueen.

The theme itself is a flexible WordPress theme for community websites which is compatible with the latest version of BuddyPress and ideal to create a vivid community website. The provided templates can also be used for other web projects like blogging or displaying a portfolio.
The security vulnerability
The K Elements plugin suffers from a privilege escalation via account takeover vulnerability. The vulnerability occurred due to broken logic on the Facebook social login process where users can log in to any other user’s account by only supplying their account’s email address. The vulnerability is fixed on version 5.4.0 and has been tracked with CVE-2024-56000.
The underlying vulnerability exists on the kleo_fb_intialize function:
function kleo_fb_intialize() {
/* If not our action, bail out */
if ( ! isset( $_POST['action'] ) || ( isset( $_POST['action'] ) && $_POST['action'] != 'fb_intialize' ) ) {
return false;
}
@error_reporting( 0 ); // Don't break the JSON result
header( 'Content-type: application/json' );
if ( is_user_logged_in() ) {
die( wp_json_encode( array( 'error' => esc_html__( 'You are already logged in.', 'kleo' ) ) ) );
}
if ( ! isset( $_REQUEST['FB_response'] ) || ! isset( $_REQUEST['FB_userdata'] ) ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Authentication required.', 'kleo' ) ) ) );
}
$FB_response = $_REQUEST['FB_response'];
$FB_userdata = $_REQUEST['FB_userdata'];
$FB_userid = $FB_userdata['id'];
if ( ! $FB_userid ) {
die( wp_json_encode( array( 'error' => esc_html__( 'Please connect your facebook account.', 'kleo' ) ) ) );
}
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'" );
$redirect = '';
$redirect_type = 'redirect';
//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 ) . "'" );
//Register user
if ( ! $user_ID ) {
------------------ CUT HERE ------------------
} else {
$logintype = 'login';
}
$user = get_user_by( 'id', $user_ID );
if ( $logintype == 'login' ) {
$redirect_to = home_url();
if ( function_exists( 'bp_is_active' ) ) {
$redirect_to = bp_core_get_user_domain( $user_ID );
}
/* Check the configured type of redirect */
if ( sq_option( 'login_redirect' ) == 'reload' ) {
$redirect_type = 'reload';
}
/**
* Filter the login redirect URL.
*
* @param string $redirect_to The redirect destination URL.
* @param string $requested_redirect_to The requested redirect destination URL passed as a parameter.
* @param WP_User|WP_Error $user WP_User object if login was successful, WP_Error object otherwise.
*
* @since 3.0.0
*
*/
$redirect = apply_filters( 'login_redirect', $redirect_to, '', $user );
}
if ( ! $redirect || empty( $redirect ) ) {
$redirect = home_url();
}
wp_set_auth_cookie( $user_ID, false, false );
/**
* Fires after the user has successfully logged in.
*
* @param string $user_login Username.
* @param WP_User $user WP_User object of the logged-in user.
*
* @since 1.5.0
*
*/
do_action( 'wp_login', $user->user_login, $user );
die ( wp_json_encode( array(
'loggedin' => true,
'type' => $logintype,
'url' => $redirect,
'redirectType' => $redirect_type,
'message' => esc_html__( 'Login successful, redirecting...', 'kleo' ),
) ) );
}
------------------ CUT HERE ------------------
First, the $FB_userid variable can be directly constructed from $_REQUEST[‘FB_userdata’]. The $user_ID object is then constructed from the $FB_userid. Since there is no proper check on the login process, users can just supply any other user’s email address and log in to the targeted account since the code will call wp_set_auth_cookie on the $user_ID.
The patch
The vendor patched the issue by performing a proper check on the Facebook login process. The function will now use kleo_verify_facebook_token_and_get_data to fetch all of the user’s data via the Facebook access token. The patch can be seen below.

Conclusion
For custom social login processes with platforms such as Facebook, Twitter, and Google, make sure to implement the best practice of the social login process of each platform and only trust response input such as email or unique user ID from the platform’s valid authentication response and don’t directly rely on the user input.
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
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.