
Woffice Theme
Unauthenticated Privilege Escalation

Woffice Theme
Unauthenticated Broken Authentication
This blog post is about the Woffice theme vulnerabilities. If you're a Woffice user, please update the theme to at least version 5.4.15.
✌️ Our users are protected from this vulnerability. Are yours?
Automatically mitigate vulnerabilities in real-time without changing code.
See pricingIdentify vulnerabilities in your plugins and get recommendations for fixes.
Request auditProtect your users, improve server health and earn additional revenue.
Patchstack for hostsAbout the Woffice Theme
The theme Woffice, which has over 15,000 sales, is a popular premium intranet/extranet theme for WordPress. This theme is bundled with a required Woffice Core plugin and is developed by Xtendify.

This premium WordPress theme provides users with team and project management functionality for advanced business management through WordPress.
The security vulnerabilities
The Woffice theme suffers from multiple critical vulnerabilities.
The first vulnerability is Privilege Escalation. This vulnerability allows unauthenticated users to register as any role on an impacted website, including privileged roles such as Administrator. In the worst-case scenario, this could lead to an attacker's full takeover of the website and malicious code installed on the server.
The second vulnerability is Unauthenticated Account Takeover (via Broken Authentication). This vulnerability allows an unauthenticated user to log in as any existing user, including the site administrator. Like the first vulnerability, the worst-case scenario could include a full site takeover, or malicious code installed onto the server.
The first vulnerability was fixed in version 5.4.12, and the second was fixed in version 5.4.15. We strongly recommend updating to at least version 5.4.15 to ensure protection from both critical vulnerabilities. These vulnerabilities were assigned CVE-2024-43153 and CVE-2024-43234, respectively.
Unauthenticated Privilege Escalation
The vulnerable code exists in the registration function, found in inc/classes/Woffice_Register.php:
public function registration()
{
/* We first check for the roles */
$register_role = woffice_validate_bool_option(woffice_get_theming_option('register_role'));
$default_role = get_option('default_role');
if (isset($_POST["reg_role"]) && $_POST["reg_role"] != false && $register_role) {
$role = $_POST["reg_role"];
} else {
$role = $default_role;
}
$user_data = array(
'user_login' => esc_attr($this->username),
'user_email' => esc_attr($this->email),
'user_pass' => esc_attr($this->password),
'first_name' => esc_attr($this->first_name),
'last_name' => esc_attr($this->last_name),
'display_name' => '',
'role' => esc_attr($role)
);
if (is_wp_error($this->validation())) {
$color_notifications = woffice_get_settings_option('color_notifications');
echo '<div class="infobox fa-exclamation-triangle" style="background-color: ' . $color_notifications . ';">';
echo '<strong>' . $this->validation()->get_error_message() . '</strong>';
echo '</div>';
} else {
/**
* Filter `woffice_register_user_data`
*
* @param array
*
* @return array
*/
$user_data = apply_filters('woffice_register_user_data', $user_data);
$register_user = wp_insert_user($user_data);
----------------- CUT HERE -----------------
This function is called by Woffice's custom Login/Registration page. When the custom Login is enabled, along with the Auto Login and Role field in the form options, this function will pass any role submitted in the $_POST["reg_role"] parameter to the wp_insert_user function, allowing the user to register with any available role. Because there are no limitations on this field, the user may register with even highly privileged roles, such as administrator.
Unauthenticated Account Takeover
Also in the inc/classes/Woffice_Register.php, this vulnerability is in the register_redirect function.
public function register_redirect(){
check_ajax_referer( 'WofficeRegisterRedirectNonce', 'security' );
// We grab the user's ID
if (isset($_POST['user_id']) && $_POST['user_id'] > 0) {
$user_id = $_POST['user_id'];
// Get the ID
$user = get_user_by( 'id', $user_id );
if( $user ) {
// Login :
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id );
do_action( 'wp_login', $user->user_login );
// Ajax content :
echo '<div class="woffice-ajax-main"><i class="fa fa-check-circle"></i> '.__('Redirecting', 'woffice').'...</div>';
}
}
wp_die();
}
Also used by Woffice's custom Login functionality, exploiting this function requires a Custom Login Page to be set, Auto Login to be enabled, and Email verification to be disabled. In this situation, an unregistered user is able to extract the WofficeRegisterRedirect security nonce from the registration page and use it to log in as any user on the impacted website by sending a request including the nonce and $_POST['user_id'] set to an existing ID (for example, 1, which is frequently the site administrator's user ID).
The Patch
For the Privilege Escalation vulnerability, the vendor applies a patch to limit which roles a user can register as. This patch implements a denylist of site-specific excluded roles, as well as a hard block on administrator or super_admin roles.

For the Unauthenticated Account Takeover vulnerability, the vendor decided the best solution was to remove the vulnerable register_redirect() function entirely.
Conclusion
The vulnerabilities discussed here highlight the importance of secure registration. Administrators, reasonably, have a very impactful amount of power when it comes to control over a WordPress site — allowing unknown users this level of privilege can be extremely dangerous.
In the context of registration, care needs to be taken to ensure that users can only register with specifically acceptable roles. When implementing a custom registration portal, we recommend utilizing allowlists of only specifically allowed roles, or at minimum allowing the site owners to create denylists of roles a new user is not able to register as — ideally with a sane set of defaults as well.
In the context of authentication, user-provided data should never be blindly used to confirm who that user is. When implementing a custom login portal, it is vital to ensure that either the user is reauthenticated (via wp_authenticate), or by confirming that they are already authenticated (e.g., with wp_get_current_user).
Timeline
🤝 You can help us make the Internet a safer place
Streamline your disclosure process to fix vulnerabilities faster and comply with CRA.
Get started for freeProtect your users too! Improve server health and earn added revenue with proactive security.
Patchstack for hostsReport vulnerabilities to our gamified bug bounty program to earn monthly cash rewards.
Learn more