Critical Vulnerability In Profile Builder Plugin Allowed Site Takeover

Description: Unauthenticated Administrator Registration
Affected Plugin: Profile Builder (Free, Pro, and Hobbyist versions affected)
Affected Versions: <= 3.1.0
CVSS Score: 10.0 (Critical)
CVSS Vector:
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Patched Version: 3.1.1

Earlier this week, a critical vulnerability was patched in the Profile Builder plugin for WordPress. This vulnerability affected the free version available on the WordPress.org repository, as well as the commercial Pro and Hobbyist variants. According to the WordPress repository more than 50,000 sites are running the free version of Profile Builder, and our estimates suggest there are roughly 15,000 installations of the Pro and Hobbyist versions, for an estimated total of 65,000 affected sites.

Profile Builder versions up to and including 3.1.0 are affected by this vulnerability. It is crucial that any site running a vulnerable version of the plugin be updated to version 3.1.1 immediately to avoid site compromise. We have deployed a firewall rule to prevent exploitation on sites running Wordfence Premium. Sites using the free version of Wordfence will receive the rule after thirty days.

In this post we’ll take a look at the vulnerability and discuss its impact. We’ll also detail some steps a site owner can take to mitigate the issue in the event that an immediate update isn’t possible.

Vulnerability Summary

Profile Builder is a plugin designed to create custom forms that allow users to register, edit their profiles, and more. It also features a custom user role editor, allowing admins to assign custom sets of privileges to their site’s users.

To implement these custom user roles in the registration process, the plugin features form handlers to assign a selected role to a new user. This user role field isn’t present by default, but can be added by an administrator to provide a list of approved roles in a drop-down menu.

An example of a Profile Builder registration form with a User Role dropdown field.

An example of a Profile Builder registration form with a User Role dropdown field.

Unfortunately, a bug in the form handler made it possible for a malicious user to submit input on form fields that didn’t exist in the actual form. Specifically, if the site’s administrator didn’t add the User Role field to the form, an attacker could still inject a user role value into their form submission.

When an administrator adds the User Role selector to a form, they have to select a list of approved roles for new users. If this list is created, only approved roles will be accepted by the form handler. However, when the User Role field isn’t present and an attacker submits a user role anyway, there is no list of approved roles and any input is accepted.

These two issues combine to allow unauthenticated attackers to register Administrator accounts on vulnerable WordPress sites. With Administrator privileges, an attacker has effectively taken over the site and can deploy malware and other backdoors freely.

These issues have been patched as of Profile Builder version 3.1.1.

Patch Details

As we mentioned in the summary above, the impact of this vulnerability is caused by the interaction of two smaller bugs.

For the first bug, the Profile Builder plugin’s form handler would process input on any of the plugin’s possible form fields, regardless of whether that field was present in the form. To patch this bug, the developers created the validation function wppb_field_exists_in_form(). This validation is now used in the handler function of each possible form field, preventing the injection of unintended values.

/**
 * Function that checks if a field type exists in a form
 * @return bool
 */
function wppb_field_exists_in_form( $field_type, $form_args ){
    if( !empty( $form_args ) && !empty( $form_args['form_fields'] ) ){
        foreach( $form_args['form_fields'] as $field ){
            if( $field['field'] === $field_type ){
                return true;
            }
        }
    }

    return false;
}

Patching this bug effectively prevents exploitation of the second one, but the developers wisely fixed it as well. In addition to confirming the custom_field_user_role field is present on the form, the field handler now explicitly denies attempts to create Administrator users.

/* handle field save */
function wppb_userdata_add_user_role( $userdata, $global_request, $form_args ){

    if( wppb_field_exists_in_form( 'Select (User Role)', $form_args ) ) {

        $roles_editor_active = false;
        $wppb_generalSettings = get_option('wppb_general_settings', 'not_found');
        if ($wppb_generalSettings != 'not_found') {
            if (!empty($wppb_generalSettings['rolesEditor']) && ($wppb_generalSettings['rolesEditor'] == 'yes')) {
                $roles_editor_active = true;
            }
        }

        if (isset($global_request['custom_field_user_role'])) {
            if ($roles_editor_active && is_array($global_request['custom_field_user_role'])) {
                $user_roles = array_map('trim', $global_request['custom_field_user_role']);
                $user_roles = array_map('sanitize_text_field', $user_roles);

                //don't allow administrator value. it should never be here but just in case make a hard check
                if (($key = array_search("administrator", $user_roles)) !== false) {
                    unset($user_roles[$key]);
                }

                $userdata['role'] = $user_roles;
            } else {
                $role = sanitize_text_field(trim($global_request['custom_field_user_role']));
                if( $role !== 'administrator' ) {//don't allow administrator value. it should never be here but just in case make a hard check
                    $userdata['role'] = $role;
                }
            }
        }
    }

    return $userdata;
}

As you can see in the if() statement on line 181, the user role assignment code will not run if wppb_field_exists_in_form() returns False. Additionally, checks on lines 197 and 204 will prevent assignment if the intended role is administrator.

Assessing Impact

Considering all of the factors of this vulnerability, we have calculated its CVSS severity score as 10.0 (Critical). View the CVSS calculation here.

This score was determined based on the following metrics:

  • Attack Vector: Network
    • The vulnerability can be exploited via HTTP(S) access to an affected site.
  • Attack Complexity: Low
    • No excessive effort is required by an attacker, just the discovery of a vulnerable form.
  • Privileges Required: None
    • The vulnerability is exploited in the user registration process, no prior authentication is necessary.
  • User Interaction: None
    • No interaction by the site’s administrator is required to exploit a vulnerable form.
  • Scope: Changed
    • The vulnerability is present in a plugin added onto a WordPress application, but successful exploitation allows access far beyond the affected plugin itself.
  • Confidentiality: High
  • Integrity: High
  • Availability: High
    • All three CIA impact scores are High in cases where a full site takeover is possible. An attacker with Administrator privileges can disrupt site behavior, harvest data, and inject malicious content at will.

Short-Term Mitigation

We strongly recommend updating Profile Builder to version 3.1.1 as soon as possible to avoid a critical security event on your site. However, we understand that some users may be restricted by update workflows and other policies that can slow down a proper response.

In the event that your site is using a vulnerable version of Profile Builder and can’t be updated immediately, it’s possible to mitigate the severity of the vulnerability by modifying your existing Profile Builder form fields. Since an attacker can only create an Administrator account if the User Role field doesn’t exist in the form, you can add this field and properly limit it to one or more authorized roles.

A screenshot of Profile Builder's interface, showing the creation of a Select (User Role) field.

A screenshot of Profile Builder’s interface, showing the creation of a Select (User Role) field.

To add this field, access the “Form Fields” page from Profile Builder’s sidebar menu. At the top of this page, a dropdown will ask you to select an option. Choose the “Select (User Role)” option under Advanced. Fill out the form that appears by giving the field a name and description, then select the role or roles that new users should be allowed to access. For most sites, selecting Subscriber and nothing else will be sufficient.

To reiterate, it’s still of critical importance that affected users update their plugins as quickly as possible even when a mitigation like this is available. This should only be relied on as a temporary measure to prevent exploitation until you can patch your site.

Timeline

  • February 10, 2020 – Profile Builder version 3.1.1 is released. “Security update” mentioned in changelog. WPVulnDB entry created by the vulnerability’s discoverer.
  • February 12, 2020 – We deployed a firewall rule to protect Wordfence Premium users from the vulnerability.
  • February 24, 2020 – Proof-of-concept (PoC) to be released, according to the WPVulnDB entry.
  • March 13, 2020 – Firewall rule to be deployed to sites running the free version of Wordfence.

Conclusion

Profile Builder versions up to and including 3.1.0 were affected by a critical vulnerability which could allow hackers to take over a site using the plugin. All variants of the plugin, including Free, Pro, and Hobbyist, contained the bugs responsible for this issue. These bugs were patched in version 3.1.1 of all variants, released on February 10th.

Wordfence Premium users are already protected by a new firewall rule, and sites still using the free version of Wordfence will receive this rule on March 13th. Even with a firewall rule in place, we still strongly recommend performing security updates to thoroughly mitigate the risk to your site.

At this time, we have seen no indication of malicious activity seeking to exploit this vulnerability. We will continue to monitor for new exploitation campaigns that may emerge over time, and will report our findings as they come. If you believe your site may have been compromised as a result of this vulnerability or any other, don’t hesitate to reach out to our Site Cleaning team.

According to the vulnerability’s entry in WPVulnDB, the discovering researcher intends to release a detailed proof-of-concept (PoC) on February 24th. While a bad actor could develop an attack script by examining the changes made in the patched version with little difficulty, the public release of a PoC commonly results in wide exploitation by hackers. It is critically important that all affected users update to version 3.1.1 as soon as possible. To help spread awareness of these concerns, please consider sharing this report with other members of the WordPress community.

Update – 02/24/2020

As promised, the original researcher’s proof-of-concept has been made public. In a new blog post, we’ve analyzed threat activity pertaining to recently patched plugins including Profile Builder. We have not yet identified an increase in attack volume since the release of a public PoC.

 

Did you enjoy this post? Share it!

Comments

1 Comment
  • Thanks for details!