The Wordfence Threat Intelligence team responsibly disclosed a Cross-Site Request Forgery(CSRF) vulnerability in WP Fluent Forms, a WordPress plugin installed on over 80,000 sites.
This vulnerability also allowed a stored Cross-Site Scripting(XSS) attack which, if successfully exploited, could be used to take over a site.
Description: Cross-Site Request Forgery to stored Cross-Site Scripting(XSS)
Affected Plugin:WP Fluent Forms
Plugin Slug: fluentform
Affected Versions: < 3.6.67
CVE ID: CVE-2021-34620
CVSS Score: 7.1 (High)
CVSS Vector:CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L
Researcher/s: Ramuel Gall
Fully Patched Version: 3.6.67
WP Fluent Forms is a popular plugin that allows site owners to easily create and manage contact forms. It uses a large set of AJAX actions in order to modify global settings and perform most actions, and all non-public AJAX actions use a single method, Acl::verify
in order to perform capability checks on these actions.
public static function verify(
$permission,
$formId = null,
$message = 'You do not have permission to perform this action.',
$json = true
)
{
$allowed = self::hasPermission($permission, $formId);
if (!$allowed) {
if ($json) {
wp_send_json_error([
'message' => $message
], 422);
} else {
throw new \Exception($message);
}
}
}
public static function hasPermission($permission, $formId = false)
{
if (current_user_can('fluentform_full_access')) {
return true;
}
$allowed = current_user_can('fluentform_full_access');
if ($allowed) {
return true;
}
if (is_array($permission)) {
foreach ($permission as $eachPermission) {
$allowed = current_user_can($eachPermission);
if ($allowed) {
return apply_filters('fluentform_verify_user_permission_' . $eachPermission, $allowed, $formId);
} else {
$isHookAllowed = apply_filters('fluentform_permission_callback', false, $eachPermission, $formId);
if ($isHookAllowed) {
return true;
}
}
}
return false;
}
$allowed = current_user_can($permission);
$allowed = apply_filters('fluentform_verify_user_permission_' . $permission, $allowed, $formId);
if ($allowed) {
return true;
}
return apply_filters('fluentform_permission_callback', false, $permission, $formId);
}
Unfortunately, however, all of these AJAX actions were vulnerable to Cross-Site Request Forgery because the Acl::verify
method did not perform a nonce check, though it did use a second method, Acl::hasPermission
in order to complete the capability check and allow for custom capabilities.
As a result, it was possible to trick an administrator into sending a request (for instance, by clicking a link leading to an attacker-controlled page that sends an XHR request or contains a self-submitting form) to make arbitrary changes to the plugin. This attack would also work against any user that had been granted full permission to access the form settings.
The most severe consequence that the team discovered was the ability to add arbitrary JavaScript to any form via the fluentform-save-form-custom_css_js
AJAX action. If malicious JavaScript were added to a form, it would be executed in the browser of any visitor that accessed the form. If an administrator visited such a form, the JavaScript could be used to create an additional malicious administrative account or to add a backdoor to a plugin or theme file.
It was also possible for an attacker to trick an administrator into granting access to the plugin settings to subscriber-level users via the fluentform_set_access_roles
AJAX action. In order for this to cause any real harm, the attacker would need to have at least a subscriber-level account on the targeted site and successfully socially engineer a vulnerable site owner. Again, an attacker would most likely abuse this access by adding malicious JavaScript to a form on the site.
In both cases, an attack would require targeted social engineering and would be unlikely to be exploited at scale. However, it would be trivial to redirect an administrator to a compromised form immediately after tricking them into sending the initial request, so it could reasonably be expected that any successful attack of this type by a competent adversary would result in full site takeover.
Bijay Pokharel
Related posts
Recent Posts
Subscribe
Cybersecurity Newsletter
You have Successfully Subscribed!
Sign up for cybersecurity newsletter and get latest news updates delivered straight to your inbox. You are also consenting to our Privacy Policy and Terms of Use.