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.
Patchstack customers are protected from this vulnerability, and no immediate action is needed from you.
For plugin developers, we have security audit services and Enterprise API for hosting companies.
About 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
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.