High Severity Vulnerabilities in PageLayer Plugin Affect Over 200,000 WordPress Sites

A few weeks ago, our Threat Intelligence team discovered several vulnerabilities present in Page Builder: PageLayer – Drag and Drop website builder, a WordPress plugin actively installed on over 200,000 sites. The plugin is from the same creators as wpCentral, a plugin within which we recently discovered a privilege escalation vulnerability.

One flaw allowed any authenticated user with subscriber-level and above permissions the ability to update and modify posts with malicious content, amongst many other things. A second flaw allowed attackers to forge a request on behalf of a site’s administrator to modify the settings of the plugin which could allow for malicious Javascript injection.

We initially reached out to the plugin’s developer on April 30, 2020 and after establishing an appropriate communication channel, we provided the full disclosure on May 1, 2020. They responded quickly on May 2, 2020 letting us know that they were beginning to work on fixes. An initial patch was released on May 2, 2020 and an optimal patch was released on May 6, 2020.

These are considered high-level security issues that could potentially lead to attackers wiping your site’s content or taking over your site. We highly recommend an immediate update to the latest version available at the time of this publication, which is version 1.1.4.

Wordfence Premium customers received a new firewall rule on April 30, 2020, to protect against exploits targeting this vulnerability. Free Wordfence users will receive this rule after thirty days, on May 30, 2020.

Description: Unprotected AJAX and Nonce Disclosure to Stored Cross-Site Scripting and Malicious Modification
Affected Plugin: Page Builder: PageLayer – Drag and Drop website builder
Plugin Slug: pagelayer
Affected Versions: <= 1.1.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 7.4 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:L
Fully Patched Version: 1.1.2

PageLayer is a very easy to use WordPress page builder plugin that claims to work with nearly all themes on the market and in the WordPress repository. It provides extended customization of pages through the use of widgets that can add page elements like buttons, tables, excerpts, products and more.

We discovered that nearly all of the AJAX action endpoints in this plugin failed to include permission checks. This meant that these actions could be executed by anyone authenticated on the site, including subscriber-level users. As standard, these AJAX endpoints only checked to see if a request was coming from /wp-admin through an authenticated session and did not check the capabilities of the user sending the request.

There were nonce checks in use in all of these functions, but nonces can be easily compromised if incorrectly implemented – for example, if a usable nonce is displayed within the source code of the site’s output. Unfortunately for the PageLayer plugin, this is precisely what happened. A usable nonce was visible in the header section of the source code of any page that had previously been edited using the PageLayer plugin. Any site visitor could find this nonce, whether they were logged in or not, allowing any unauthenticated user the ability to obtain a legitimate nonce for the plugin’s AJAX actions.

PageLayer nonce obtainable from page source.

Using a single nonce as the mechanism for authorization control caused various security issues in the functionalities of the page builder due to this nonce being so easily obtainable.

WordPress nonces should never be used as a means of authorization as they can easily be compromised if implemented improperly or if a loophole is found. WordPress nonces are designed to be used for CSRF protection, not authorization control. Implementing capability checks in conjunction with CSRF protection on sensitive functions for full verification provides protection to ensure a request is coming from an authorized user.

The Impact

As previously mentioned, several AJAX functions were affected, causing a large variety of potential impacts. A few of the most impactful actions were wp_ajax_pagelayer_save_content, wp_ajax_pagelayer_update_site_title, and wp_ajax_pagelayer_save_template.

add_action('wp_ajax_pagelayer_save_content', 'pagelayer_save_content');
add_action('wp_ajax_pagelayer_update_site_title', 'pagelayer_update_site_title');
add_action('wp_ajax_pagelayer_save_template', 'pagelayer_save_template');

The pagelayer_save_content function is used to save a page’s data through the page builder. The lack of permission checks on this function allowed authenticated users, regardless of permissions, the ability to change any data on a page edited with PageLayer.

function pagelayer_save_content(){

	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');

	$content = $_POST['pagelayer_update_content'];

	$postID = (int) $_GET['postID'];

	if(empty($postID)){
		$msg['error'] =  __pl('invalid_post_id');
	}

An attacker could wipe the pages completely or inject any content they would like on the site’s pages and posts. In addition, a few widgets allowed Javascript to be injected, including the “Button” widget. There is no sanitization on the “Button” widget’s text, which allows for malicious Javascript to be used as a text. This Javascript would execute once any user browsed to a page containing that button.

PageLayer button with alert JS injected.

The pagelayer_update_site_title function is used to update a site’s title. The lack of permission checks on this function allowed authenticated users the ability to change a site title to any title of their choosing. Though less detrimental, this could still affect your sites search engine ranking if unnoticed for an extended period of time.

function pagelayer_update_site_title(){
	global $wpdb;

	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');

	$site_title = $_POST['site_title'];

	update_option('blogname', $site_title);

	$wpdb->query("UPDATE `sm_sitemeta` 
				SET meta_value = '".$site_title."'
				WHERE meta_key = 'site_name'");
	wp_die();
}

The pagelayer_save_template function is used to save PageLayer templates for the PageLayer Theme Builder. The lack of permission checks on this function allowed authenticated users the ability to create new PageLayer templates that were saved as new posts.

function pagelayer_save_template() {
	
	// Some AJAX security
	check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce');
	
	$done = [];
	
	$post_id = (int) $_GET['postID'];
	
	// We need to create the post
	if(empty($post_id)){
	
		// Get the template type
		if(empty($_POST['pagelayer_template_type'])){
			$done['error'] = __pl('temp_error_type');
			pagelayer_json_output($done);
		}
		
		$ret = wp_insert_post([
			'post_title' => $_POST['pagelayer_lib_title'],
			'post_type' => 'pagelayer-template',
			'post_status' => 'publish',
			'comment_status' => 'closed',
			'ping_status' => 'closed'
		]);

Though this function was intended to be used in the PRO version of the plugin, the function could still be executed in the free version, affecting all 200,000+ users of the PageLayer plugin. An attacker could create a new template, which created a new page on the site, and inject malicious Javascript in the same way they could with the pagelayer_save_content function.

Malicious Javascript can be used to inject new administrative users, redirect site visitors, and even exploit a site’s user’s browser to compromise their computer.

The Patch

In the latest version of the plugin, the developers implemented permissions checks on all of the sensitive functions that could make changes to a site, and reconfigured the plugin to create separate nonces for the public and administrative areas of a WordPress site.

	// Are you allowed to edit ?
	if(!pagelayer_user_can_edit($postID)){
		$msg['error'][] =  __pl('no_permission');
		pagelayer_json_output($msg);
	}
Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
Affected Plugin: Page Builder: PageLayer – Drag and Drop website builder
Plugin Slug: pagelayer
Affected Versions: <= 1.1.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 1.1.2

The PageLayer plugin registers a settings area where configuration changes can be made. This includes functionality such as where the editor is enabled, basic content settings, basic information configurations, and more.

PageLayer settings area.

The settings update function used a capability check to verify that a user attempting to make any changes had the appropriate permissions. However, there was no CSRF protection to verify the legitimacy of any request attempting to update a site’s settings. This made it possible for attackers to trick an administrator into sending a request to update any of the PageLayer settings.

function pagelayer_settings_page(){

	$option_name = 'pl_gen_setting' ;
	$new_value = '';

	if(isset($_REQUEST['pl_gen_setting'])){
		$new_value = $_REQUEST['pl_gen_setting'];
		
		if ( get_option( $option_name ) !== false ) {
	
			// The option already exists, so we just update it.
			update_option( $option_name, $new_value );

The “Information” tab in the settings area provides site owners with a way to set a default address, telephone number, and contact email address that are displayed whenever the corresponding widgets were used on a page. There was no sanitization on the address or telephone number settings, and due to the administrator’s capability to use unfiltered_html, Javascript could be injected into these settings.

PageLayer Address updated with alert JS.

The Impact

This allowed attackers the ability to inject malicious scripts while exploiting the CSRF vulnerability in the settings. If the widget was already enabled, any injected malicious scripts would execute whenever someone browsed to a page containing that widget. If the widget was not yet enabled, the malicious scripts could be executed once an administrator started editing and inserting the widget into a page. As always, these scripts can do things like create a new administrative account and redirect users to malicious sites.

The Patch

In the patched version of the plugin, the developers implemented CSRF protection consisting of a WordPress nonce and verification of that nonce when updating settings.

	if(isset($_REQUEST['submit'])){
		check_admin_referer('pagelayer-options');
	}

PoC Walkthrough: pagelayer_save_content

Disclosure Timeline

April 24, 2020 to April 30, 2020 – Initial discovery of minor security flaw and deeper security analysis of plugin.
April 30, 2020 – Firewall rule was released for Wordfence Premium customers. We made our initial contact attempt with the plugin’s development team.
May 1, 2020 – The plugin’s development team confirms appropriate inbox for handling discussion. We provide full disclosure.
May 2, 2020 – Developer acknowledges receipt and confirms that they are beginning to work on fixes. An update is released the same day.
May 4, 2020 – We analyze the fixes and discover a few security issues left unpatched and responsibly disclose these issues to the developer.
May 6, 2020 – Developer releases the final sufficient patch.
May 30, 2020 – Free Wordfence users receive firewall rule.

Conclusion

In today’s post, we detailed several flaws related to unprotected AJAX actions and nonce disclosure that allowed for attackers to make several malicious modifications to a site’s pages and posts in addition to providing attackers with the ability to inject malicious Javascript. These flaws have been fully patched in version 1.1.2. We recommend that users immediately update to the latest version available, which is version 1.1.4 at the time of this publication.

Sites running Wordfence Premium have been protected from attacks against this vulnerability since April 30, 2020. Sites running the free version of Wordfence will recieve this firewall rule update on May 30, 2020. If you know a friend or colleague who is using this plugin on their site, we highly recommend forwarding this advisory to them to help keep their sites protected.

The post High Severity Vulnerabilities in PageLayer Plugin Affect Over 200,000 WordPress Sites appeared first on Wordfence.

Read More

The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites

On May 6, our Threat Intelligence team was alerted to a zero-day vulnerability present in Elementor Pro, a WordPress plugin installed on approximately 1 million sites. That vulnerability was being exploited in conjunction with another vulnerability found in Ultimate Addons for Elementor, a WordPress plugin installed on approximately 110,000 sites.

We immediately released a firewall rule to protect Wordfence Premium users and contacted Elementor about the vulnerability. As this vulnerability was being actively exploited, we also publicly notified the community of the vulnerability to help protect users from being compromised.

Elementor quickly released an update for Elementor Pro the same day we published a notice on the Wordfence blog. In today’s post, we provide the technical details of the two vulnerabilities along with a closer look at how these two vulnerabilities were used together to compromise WordPress websites using these plugins.

We urge any website owners who have not yet updated to the latest versions of these plugins to do so immediately. For Elementor Pro, that is version 2.9.4 and in Ultimate Addons for Elementor, that is version 1.24.2.

Ultimate Addons for Elementor

Description: Registration Bypass
Affected Plugin: Ultimate Addons for Elementor
Plugin Slug: ultimate-elementor
Affected Versions: <= 1.24.1
CVE ID: CVE-2020-13125
CVSS Score: 7.2 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Fully Patched Version: 1.24.2

Ultimate Addons for Elementor is a plugin made by Brainstorm Force. It is an extension to Elementor, providing many additional widgets to use with Elementor.

One of the widgets adds a registration form, called the “User Registration Form” to any page. This is an easily customizable registration form that can be placed anywhere on the site. Unfortunately, there was a flaw in the functionality of this form that allowed for users to register even when registration was disabled, and even if the form widget was not actively in use on the site.

Is User Registration enabled?

The developers registered both nopriv and regular AJAX actions tied to the get_form_data function in order to provide functionality for the User Registration Form widget.

	public function __construct() {
		parent::__construct();

		add_action( 'wp_ajax_uael_register_user', array( $this, 'get_form_data' ) );
		add_action( 'wp_ajax_nopriv_uael_register_user', array( $this, 'get_form_data' ) );
		add_filter( 'wp_new_user_notification_email', array( $this, 'custom_wp_new_user_notification_email' ), 10, 3 );

Diving into the get_form_data function, we see that it was designed to retrieve the information submitted in the registration form. This data was then used to create a new user on the site using the WordPress wp_insert_user hook. Nowhere in the function did it verify that user registration was enabled on the site, nor did it do any alternative checks to verify that the registration form widget was active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data     = array();
		$error    = array();
		$response = array();

		if ( isset( $_POST['data'] ) ) {

			$data = $_POST['data'];

*Note several lines are omitted for brevity.

			$user_args = apply_filters(
					'uael_register_insert_user_args',
					array(
						'user_login'      => isset( $user_login ) ? $user_login : '',
						'user_pass'       => isset( $user_pass ) ? $user_pass : '',
						'user_email'      => isset( $user_email ) ? $user_email : '',
						'first_name'      => isset( $first_name ) ? $first_name : '',
						'last_name'       => isset( $last_name ) ? $last_name : '',
						'user_registered' => gmdate( 'Y-m-d H:i:s' ),
						'role'            => isset( $user_role ) ? $user_role : '',
					)
				);

				$result = wp_insert_user( $user_args );

These missing checks were what made it possible for attackers to bypass the user registration settings on a WordPress site. Fortunately, Brainstorm Force added checks in the latest version to verify both that user registration is enabled and that the widget is active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data             = array();
		$error            = array();
		$response         = array();
		$allow_register   = get_option( 'users_can_register' );
		$is_widget_active = UAEL_Helper::is_widget_active( 'RegistrationForm' );

		if ( isset( $_POST['data'] ) && '1' === $allow_register && true === $is_widget_active ) {

			$data = $_POST['data'];

Registration Nonce is always displayed

Though nonces are primarily used to mitigate CSRF attacks and verify the legitimacy of a request, they can also act as a fail-safe in instances like this where a function contains a small flaw, that is, if the nonce is undiscoverable by an attacker.

The get_form_data function did use nonce verification that could have potentially stopped rogue user registration. However, we discovered that the form_nonce was always visible in the source code of a page where a UA for Elementor widget was enabled, even when there was no form present on the page.

/**
	 * Setup Actions Filters.
	 *
	 * @since 0.0.1
	 */
	private function setup_actions_filters() {

		add_shortcode( 'uael-template', array( $this, 'uael_template_shortcode' ) );

		add_action( 'elementor/init', array( $this, 'elementor_init' ) );

		add_action( 'elementor/elements/categories_registered', array( $this, 'widget_category' ) );

		add_action( 'elementor/frontend/after_register_scripts', array( $this, 'register_widget_scripts' ) );

*Note several lines are omitted for brevity.


			wp_localize_script(
			'jquery',
			'uaelRegistration',
			array(
				'invalid_mail'       => __( 'Enter valid Email!', 'uael' ),
				'pass_unmatch'       => __( 'The specified password do not match!', 'uael' ),
				'required'           => __( 'This Field is required!', 'uael' ),
				'form_nonce'         => wp_create_nonce( 'uael-form-nonce' ),
				'incorrect_password' => __( 'Error: The Password you have entered is incorrect.', 'uael' ),
				'invalid_username'   => __( 'Unknown username. Check again or try your email address.', 'uael' ),
				'invalid_email'      => __( 'Unknown email address. Check again or try your username.', 'uael' ),
			)
		);
	}

This meant that attackers just needed to scrape the source code of pages on a site running this plugin for var uaelRegistration. If that site had at least one widget in use on any page, they would be granted a usable nonce to register on the site.

A look at the discoverable UAE nonce in the source code of a page with a UAE widget enabled.

The Exploit

Combined, these flaws made it possible for attackers to register as a subscriber on any vulnerable site and potentially use that access to pivot and exploit vulnerabilities that required subscriber level access. This is precisely what we saw being exploited in the case of the Elementor Pro vulnerability.

Special thanks to Ramuel Gall for his research contributions on this vulnerability.

Elementor Pro

Description: Authenticated Arbitrary File Upload
Affected Plugin: Elementor Pro
Plugin Slug: elementor-pro
Affected Versions: <= 2.9.3
CVE ID: CVE-2020-13126
CVSS Score: 9.9 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 2.9.4

Elementor is a popular WordPress page builder plugin, currently installed on over 5 million WordPress sites. The Pro version adds additional enhancements like the ability to upload custom icons and fonts. It also adds over 50 additional widgets to improve the page building process along with enhanced customizability.

When a plugin introduces the ability to upload files, regardless of the file type, the proper control measures should always be included in order to prevent unauthorized users from uploading files or bypassing any file filters or privileges established on the site.

Unfortunately, the ‘Custom Icon’ upload functionality in Elementor Pro did not have appropriate measures in place. Attackers discovered an effective way to bypass restrictions on which file types could be uploaded, and once authenticated they were able to upload PHP files like webshells and backdoors.

Lack of Permissions Check

Elementor Pro registers an AJAX endpoint used to trigger the icon upload function. Neither the AJAX action nor the upload function had any permission checks, allowing any authenticated user, including those with minimal permissions, the ability to trigger the function and upload a .zip file.

	public function register_ajax_actions( Ajax $ajax ) {
		$ajax->register_ajax_action( 'pro_assets_manager_custom_icon_upload', [ $this, 'custom_icons_upload_handler' ] );

Fortunately, the patched version of the plugin implemented a permissions check on the custom_icons_upload_handler function that blocks low-level users from being able to upload files.

public function custom_icons_upload_handler( $data ) {
		if ( ! current_user_can( Icons_Manager::CAPABILITY ) ) {
			return new \WP_Error( Exceptions::FORBIDDEN, 'Access denied.' );
		}

Unchecked Uploads

It appears that the custom icon upload functionality was intended to only allow .zip files that were created from the Fontello, IcoMoon, or Fontastic icon creation sites. It did this by checking the files included in the .zip file and verifying that those aligned with the files generated from the trusted icon sources. However, the plugin never checks to verify if any additional files have been included in those .zip files.

	$supported_icon_sets = self::get_supported_icon_sets();
		foreach ( $supported_icon_sets as $key => $handler ) {
			/**
			 * @var IconSets\Icon_Set_Base $icon_set_handler
			 */
			$icon_set_handler = new $handler( $results['directory'] );

			if ( ! $icon_set_handler ) {
				continue;
			}
			if ( ! $icon_set_handler->is_valid() ) {
				continue;

This made it possible for attackers to include malicious files in a trusted .zip file, bypassing the restrictions the plugin had in place. This included .php files.

Discoverable Nonce

There was a nonce check on the function, but just like we saw in the Ultimate Addons for Elementor plugin, the nonce was easily discoverable due to being included in var elementorCommonConfig as “ajax” in the page source of all administrative dashboard pages.

A closer look at the Elementor Pro nonce discovered in the page source of /wp-admin.

An attacker could find a usable nonce by scraping the page source of the /wp-admin dashboard while authenticated. This could then be used as a legitimate Elementor AJAX nonce to execute the vulnerable action and upload crafted .zip files.

The Exploit

These three flaws made it possible for attackers to upload arbitrary files by creating a Fontello, IcoMoon, or Fontastic icon .zip file, extracting that file, injecting arbitrary files of their choice to the folder, re-compressing the .zip file and uploading it to the site via the AJAX action.

Uploaded .zip files are extracted into the /wp-content/upload/elementor/custom-icon directory in a newly generated folder. If the site owner previously had not uploaded any custom icons, the malicious files would be located in the /-1 folder. If there were previously uploaded custom-icon files that directory may have been a different number such as /-5, and the attacker would need to use brute force in order to find the directory into which their malicious payload had been extracted.

An attacker would be able access any newly uploaded files, like a webshell, by going directly to the file:

https://example.com/wp-content/wp-content/upload/elementor/custom-icon/-1/backdoor.php

If the file uploaded was a .php file, the code would also be executed upon access. This allowed for remote code execution (RCE) and ultimately the total compromise of the WordPress site and hosting environment.

Disclosure Timeline for Elementor Pro

May 5, 2020 – Wordfence notified of recently patched vulnerability in Ultimate Addons for Elementor. In the same notice, it was mentioned that Elementor Pro may have a “bug” that caused rogue files present in the /custom-icons directory. We begin to investigate Elementor Pro to determine if there is a security flaw present. We conclude that there is an authenticated arbitrary file upload vulnerability present.
May 5, 2020 – We quickly provision Premium customers with a firewall rule to provide protection against the vulnerability found in Elementor Pro.
May 5, 2020 – We contact the team at Elementor to alert them of the vulnerability’s presence.
May 5, 2020 – Hosting company provides us with log files that confirm this is being actively exploited.
May 6, 2020 – We publish a public service announcement with limited details to inform users how to secure their site until a patch is available.
May 6, 2020 – Elementor releases a patch for Elementor Pro.
June 4, 2020 – Wordfence free users receive firewall rule.

Attack Scenario Walkthrough

Conclusion

In today’s post, we provided technical details of the vulnerability found in the Elementor Pro plugin and how this vulnerability was used in active exploits in conjunction with the vulnerability found in Ultimate Addons for Elementor. These flaws have both been patched and we recommend that users update to the latest versions available immediately.

Sites running Wordfence Premium have been protected from attacks against the vulnerability in Elementor Pro since May 5, 2020. Sites running the free version of Wordfence will receive the firewall rule update on June 4, 2020. If you know a friend or colleague who is running one, or both, of these plugins on their site, we highly recommend forwarding this to them immediately to help them secure their site.

Special thank you to the team at Elementor for working quickly to get a patch out to protect Elementor Pro users. Also, thank you again to Ramuel Gall, Kathy Zant, Gerroald Barron, and Stephen Rees-Carter from the Wordfence team for their assistance in researching this attack and testing mitigations.

The post The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites appeared first on Wordfence.

Read More

The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites

On May 6, our Threat Intelligence team was alerted to a zero-day vulnerability present in Elementor Pro, a WordPress plugin installed on approximately 1 million sites. That vulnerability was being exploited in conjunction with another vulnerability found in Ultimate Addons for Elementor, a WordPress plugin installed on approximately 110,000 sites.

We immediately released a firewall rule to protect Wordfence Premium users and contacted Elementor about the vulnerability. As this vulnerability was being actively exploited, we also publicly notified the community of the vulnerability to help protect users from being compromised.

Elementor quickly released an update for Elementor Pro the same day we published a notice on the Wordfence blog. In today’s post, we provide the technical details of the two vulnerabilities along with a closer look at how these two vulnerabilities were used together to compromise WordPress websites using these plugins.

We urge any website owners who have not yet updated to the latest versions of these plugins to do so immediately. For Elementor Pro, that is version 2.9.4 and in Ultimate Addons for Elementor, that is version 1.24.2.

Ultimate Addons for Elementor

Description: Registration Bypass
Affected Plugin: Ultimate Addons for Elementor
Plugin Slug: ultimate-elementor
Affected Versions: <= 1.24.1
CVE ID: CVE-2020-13125
CVSS Score: 7.2 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Fully Patched Version: 1.24.2

Ultimate Addons for Elementor is a plugin made by Brainstorm Force. It is an extension to Elementor, providing many additional widgets to use with Elementor.

One of the widgets adds a registration form, called the “User Registration Form” to any page. This is an easily customizable registration form that can be placed anywhere on the site. Unfortunately, there was a flaw in the functionality of this form that allowed for users to register even when registration was disabled, and even if the form widget was not actively in use on the site.

Is User Registration enabled?

The developers registered both nopriv and regular AJAX actions tied to the get_form_data function in order to provide functionality for the User Registration Form widget.

	public function __construct() {
		parent::__construct();

		add_action( 'wp_ajax_uael_register_user', array( $this, 'get_form_data' ) );
		add_action( 'wp_ajax_nopriv_uael_register_user', array( $this, 'get_form_data' ) );
		add_filter( 'wp_new_user_notification_email', array( $this, 'custom_wp_new_user_notification_email' ), 10, 3 );

Diving into the get_form_data function, we see that it was designed to retrieve the information submitted in the registration form. This data was then used to create a new user on the site using the WordPress wp_insert_user hook. Nowhere in the function did it verify that user registration was enabled on the site, nor did it do any alternative checks to verify that the registration form widget was active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data     = array();
		$error    = array();
		$response = array();

		if ( isset( $_POST['data'] ) ) {

			$data = $_POST['data'];

*Note several lines are omitted for brevity.

			$user_args = apply_filters(
					'uael_register_insert_user_args',
					array(
						'user_login'      => isset( $user_login ) ? $user_login : '',
						'user_pass'       => isset( $user_pass ) ? $user_pass : '',
						'user_email'      => isset( $user_email ) ? $user_email : '',
						'first_name'      => isset( $first_name ) ? $first_name : '',
						'last_name'       => isset( $last_name ) ? $last_name : '',
						'user_registered' => gmdate( 'Y-m-d H:i:s' ),
						'role'            => isset( $user_role ) ? $user_role : '',
					)
				);

				$result = wp_insert_user( $user_args );

These missing checks were what made it possible for attackers to bypass the user registration settings on a WordPress site. Fortunately, Brainstorm Force added checks in the latest version to verify both that user registration is enabled and that the widget is active.

	/**
	 * Get Form Data via AJAX call.
	 *
	 * @since 1.18.0
	 * @access public
	 */
	public function get_form_data() {

		check_ajax_referer( 'uael-form-nonce', 'nonce' );

		$data             = array();
		$error            = array();
		$response         = array();
		$allow_register   = get_option( 'users_can_register' );
		$is_widget_active = UAEL_Helper::is_widget_active( 'RegistrationForm' );

		if ( isset( $_POST['data'] ) && '1' === $allow_register && true === $is_widget_active ) {

			$data = $_POST['data'];

Registration Nonce is always displayed

Though nonces are primarily used to mitigate CSRF attacks and verify the legitimacy of a request, they can also act as a fail-safe in instances like this where a function contains a small flaw, that is, if the nonce is undiscoverable by an attacker.

The get_form_data function did use nonce verification that could have potentially stopped rogue user registration. However, we discovered that the form_nonce was always visible in the source code of a page where a UA for Elementor widget was enabled, even when there was no form present on the page.

/**
	 * Setup Actions Filters.
	 *
	 * @since 0.0.1
	 */
	private function setup_actions_filters() {

		add_shortcode( 'uael-template', array( $this, 'uael_template_shortcode' ) );

		add_action( 'elementor/init', array( $this, 'elementor_init' ) );

		add_action( 'elementor/elements/categories_registered', array( $this, 'widget_category' ) );

		add_action( 'elementor/frontend/after_register_scripts', array( $this, 'register_widget_scripts' ) );

*Note several lines are omitted for brevity.


			wp_localize_script(
			'jquery',
			'uaelRegistration',
			array(
				'invalid_mail'       => __( 'Enter valid Email!', 'uael' ),
				'pass_unmatch'       => __( 'The specified password do not match!', 'uael' ),
				'required'           => __( 'This Field is required!', 'uael' ),
				'form_nonce'         => wp_create_nonce( 'uael-form-nonce' ),
				'incorrect_password' => __( 'Error: The Password you have entered is incorrect.', 'uael' ),
				'invalid_username'   => __( 'Unknown username. Check again or try your email address.', 'uael' ),
				'invalid_email'      => __( 'Unknown email address. Check again or try your username.', 'uael' ),
			)
		);
	}

This meant that attackers just needed to scrape the source code of pages on a site running this plugin for var uaelRegistration. If that site had at least one widget in use on any page, they would be granted a usable nonce to register on the site.

A look at the discoverable UAE nonce in the source code of a page with a UAE widget enabled.

The Exploit

Combined, these flaws made it possible for attackers to register as a subscriber on any vulnerable site and potentially use that access to pivot and exploit vulnerabilities that required subscriber level access. This is precisely what we saw being exploited in the case of the Elementor Pro vulnerability.

Special thanks to Ramuel Gall for his research contributions on this vulnerability.

Elementor Pro

Description: Authenticated Arbitrary File Upload
Affected Plugin: Elementor Pro
Plugin Slug: elementor-pro
Affected Versions: <= 2.9.3
CVE ID: CVE-2020-13126
CVSS Score: 9.9 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 2.9.4

Elementor is a popular WordPress page builder plugin, currently installed on over 5 million WordPress sites. The Pro version adds additional enhancements like the ability to upload custom icons and fonts. It also adds over 50 additional widgets to improve the page building process along with enhanced customizability.

When a plugin introduces the ability to upload files, regardless of the file type, the proper control measures should always be included in order to prevent unauthorized users from uploading files or bypassing any file filters or privileges established on the site.

Unfortunately, the ‘Custom Icon’ upload functionality in Elementor Pro did not have appropriate measures in place. Attackers discovered an effective way to bypass restrictions on which file types could be uploaded, and once authenticated they were able to upload PHP files like webshells and backdoors.

Lack of Permissions Check

Elementor Pro registers an AJAX endpoint used to trigger the icon upload function. Neither the AJAX action nor the upload function had any permission checks, allowing any authenticated user, including those with minimal permissions, the ability to trigger the function and upload a .zip file.

	public function register_ajax_actions( Ajax $ajax ) {
		$ajax->register_ajax_action( 'pro_assets_manager_custom_icon_upload', [ $this, 'custom_icons_upload_handler' ] );

Fortunately, the patched version of the plugin implemented a permissions check on the custom_icons_upload_handler function that blocks low-level users from being able to upload files.

public function custom_icons_upload_handler( $data ) {
		if ( ! current_user_can( Icons_Manager::CAPABILITY ) ) {
			return new \WP_Error( Exceptions::FORBIDDEN, 'Access denied.' );
		}

Unchecked Uploads

It appears that the custom icon upload functionality was intended to only allow .zip files that were created from the Fontello, IcoMoon, or Fontastic icon creation sites. It did this by checking the files included in the .zip file and verifying that those aligned with the files generated from the trusted icon sources. However, the plugin never checks to verify if any additional files have been included in those .zip files.

	$supported_icon_sets = self::get_supported_icon_sets();
		foreach ( $supported_icon_sets as $key => $handler ) {
			/**
			 * @var IconSets\Icon_Set_Base $icon_set_handler
			 */
			$icon_set_handler = new $handler( $results['directory'] );

			if ( ! $icon_set_handler ) {
				continue;
			}
			if ( ! $icon_set_handler->is_valid() ) {
				continue;

This made it possible for attackers to include malicious files in a trusted .zip file, bypassing the restrictions the plugin had in place. This included .php files.

Discoverable Nonce

There was a nonce check on the function, but just like we saw in the Ultimate Addons for Elementor plugin, the nonce was easily discoverable due to being included in var elementorCommonConfig as “ajax” in the page source of all administrative dashboard pages.

A closer look at the Elementor Pro nonce discovered in the page source of /wp-admin.

An attacker could find a usable nonce by scraping the page source of the /wp-admin dashboard while authenticated. This could then be used as a legitimate Elementor AJAX nonce to execute the vulnerable action and upload crafted .zip files.

The Exploit

These three flaws made it possible for attackers to upload arbitrary files by creating a Fontello, IcoMoon, or Fontastic icon .zip file, extracting that file, injecting arbitrary files of their choice to the folder, re-compressing the .zip file and uploading it to the site via the AJAX action.

Uploaded .zip files are extracted into the /wp-content/upload/elementor/custom-icon directory in a newly generated folder. If the site owner previously had not uploaded any custom icons, the malicious files would be located in the /-1 folder. If there were previously uploaded custom-icon files that directory may have been a different number such as /-5, and the attacker would need to use brute force in order to find the directory into which their malicious payload had been extracted.

An attacker would be able access any newly uploaded files, like a webshell, by going directly to the file:

https://example.com/wp-content/wp-content/upload/elementor/custom-icon/-1/backdoor.php

If the file uploaded was a .php file, the code would also be executed upon access. This allowed for remote code execution (RCE) and ultimately the total compromise of the WordPress site and hosting environment.

Disclosure Timeline for Elementor Pro

May 5, 2020 – Wordfence notified of recently patched vulnerability in Ultimate Addons for Elementor. In the same notice, it was mentioned that Elementor Pro may have a “bug” that caused rogue files present in the /custom-icons directory. We begin to investigate Elementor Pro to determine if there is a security flaw present. We conclude that there is an authenticated arbitrary file upload vulnerability present.
May 5, 2020 – We quickly provision Premium customers with a firewall rule to provide protection against the vulnerability found in Elementor Pro.
May 5, 2020 – We contact the team at Elementor to alert them of the vulnerability’s presence.
May 5, 2020 – Hosting company provides us with log files that confirm this is being actively exploited.
May 6, 2020 – We publish a public service announcement with limited details to inform users how to secure their site until a patch is available.
May 6, 2020 – Elementor releases a patch for Elementor Pro.
June 4, 2020 – Wordfence free users receive firewall rule.

Attack Scenario Walkthrough

Conclusion

In today’s post, we provided technical details of the vulnerability found in the Elementor Pro plugin and how this vulnerability was used in active exploits in conjunction with the vulnerability found in Ultimate Addons for Elementor. These flaws have both been patched and we recommend that users update to the latest versions available immediately.

Sites running Wordfence Premium have been protected from attacks against the vulnerability in Elementor Pro since May 5, 2020. Sites running the free version of Wordfence will receive the firewall rule update on June 4, 2020. If you know a friend or colleague who is running one, or both, of these plugins on their site, we highly recommend forwarding this to them immediately to help them secure their site.

Special thank you to the team at Elementor for working quickly to get a patch out to protect Elementor Pro users. Also, thank you again to Ramuel Gall, Kathy Zant, Gerroald Barron, and Stephen Rees-Carter from the Wordfence team for their assistance in researching this attack and testing mitigations.

The post The Elementor Attacks: How Creative Hackers Combined Vulnerabilities to Take Over WordPress Sites appeared first on Wordfence.

Read More

Vulnerability in Google WordPress Plugin Grants Attacker Search Console Access

On April 21st, our Threat Intelligence team discovered a vulnerability in Site Kit by Google, a WordPress plugin installed on over 300,000 sites. This flaw allows any authenticated user, regardless of capability, to become a Google Search Console owner for any site running the Site Kit by Google plugin.

We filed a security issue report with Google on April 21, 2020. A patch was released a few weeks later on May 7, 2020.

This is considered a critical security issue that could lead to attackers obtaining owner access to your site in Google Search Console. Owner access allows an attacker to modify sitemaps, remove pages from Google search engine result pages (SERPs), or to facilitate black hat SEO campaigns. We strongly recommend an immediate update to the latest version of this plugin. At the time of writing, that is version 1.8.0 of Site Kit by Google.

Wordfence Premium customers received a new firewall rule on April 21, 2020 to protect against exploits targeting this vulnerability. Free Wordfence users will receive this rule after thirty days, on May 21, 2020.

Description: Google Search Console Privilege Escalation
Affected Plugin: Site Kit by Google
Plugin Slug: google-site-kit
Affected Versions: <= 1.7.1
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 9.1 (Critical)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L
Fully Patched Version: 1.8.0

Site Kit by Google is a plugin used to obtain and display insights on a site’s visitors and search performance as well as advertising performance, page speed insights and other metrics from Google services in the WordPress dashboard. It does this by initially connecting to a Google Search Console account, later providing additional capabilities to connect to Analytics, AdSense, PageSpeed Insights, Optimize, and Tag Manager.

Site Kit by Google Dashboard.

In order to establish the first connection with Site Kit and Google Search Console, the plugin generates a proxySetupURL that is used to redirect a site’s administrator to Google OAuth and run the site owner verification process through a proxy.

proxySetupURL Disclosure

Due to the lack of capability checks on the admin_enqueue_scripts action, the proxySetupURL was displayed as part of the HTML source code of admin pages to any authenticated user accessing the /wp-admin dashboard.

More specifically, the admin_enqueue_scripts action triggers the enqueue_minimal_admin_script function which enqueues the googlesitekit-base assest and ultimately includes the ‘googlesitekit-base-data‘ that returns the inline base data. This includes the proxySetupURL.

	new Script_Data(
				'googlesitekit-base-data',
				array(
					'global'        => '_googlesitekitBaseData',
					'data_callback' => function () {
						return $this->get_inline_base_data();
					},
				)
			),

Here is a look at the inline_js_base_data function that retrieves the data to display in the WordPress dashboard’s source code as part of the the admin_enqueue_scripts action. This includes the proxySetupURL.

	/**
	 * Modifies the base data to pass to JS.
	 *
	 * @since 1.2.0
	 *
	 * @param array $data Inline JS data.
	 * @return array Filtered $data.
	 */
	private function inline_js_base_data( $data ) {
		$first_admin_id  = (int) $this->first_admin->get();
		$current_user_id = get_current_user_id();

		// If no first admin is stored yet and the current user is one, consider them the first.
		if ( ! $first_admin_id && current_user_can( Permissions::MANAGE_OPTIONS ) ) {
			$first_admin_id = $current_user_id;
		}
		$data['isFirstAdmin'] = ( $current_user_id === $first_admin_id );
		$data['splashURL']    = esc_url_raw( $this->context->admin_url( 'splash' ) );

		$auth_client = $this->get_oauth_client();
		if ( $auth_client->using_proxy() ) {
			$access_code                 = (string) $this->user_options->get( Clients\OAuth_Client::OPTION_PROXY_ACCESS_CODE );
			$data['proxySetupURL']       = esc_url_raw( $auth_client->get_proxy_setup_url( $access_code ) );
			$data['proxyPermissionsURL'] = esc_url_raw( $auth_client->get_proxy_permissions_url() );
		}

		return $data;
	}

A closer look at the data discoverable in the source code of the admin dashboard:

proxySetupURL found in the source code.

This was fixed in the latest version of the plugin by the addition of a capability check on the admin_enqueue_scripts action. This prohibits the inline_js_base_data from being included in administrative pages for users who do not have the appropriate privileges, such as subscribers. This prevents the proxySetupURL from being displayed to unauthorized users.

	add_action( 'admin_enqueue_scripts', $register_callback );
		add_action( 'wp_enqueue_scripts', $register_callback );

		add_action(
			'admin_enqueue_scripts',
			function() {
				if ( ! current_user_can( Permissions::AUTHENTICATE ) ) {
					return;
				}
				$this->enqueue_minimal_admin_script();
			}
		);

Unprotected Verification

In addition to displaying the proxySetupURL to any authenticated user, we discovered that the verification request used to verify a site’s ownership was a registered admin action that, again, did not have any capability checks. This allowed verification requests to come from any authenticated WordPress user, including those with minimal permissions.

The admin_action_googlesitekit_proxy_setup action was registered here.

	add_action(
			'admin_action_' . Google_Proxy::ACTION_SETUP,
			function () {
				$this->verify_proxy_setup_nonce();
			},
			-1
		);

		add_action(
			'admin_action_' . Google_Proxy::ACTION_SETUP,
			function () {
				$code      = $this->context->input()->filter( INPUT_GET, 'googlesitekit_code', FILTER_SANITIZE_STRING );
				$site_code = $this->context->input()->filter( INPUT_GET, 'googlesitekit_site_code', FILTER_SANITIZE_STRING );

				$this->handle_site_code( $code, $site_code );
				$this->redirect_to_proxy( $code );
			}
		);

This is the function that handles the verification request:

	/**
	 * Handles receiving a verification token for a user by the authentication proxy.
	 *
	 * @since 1.1.0
	 * @since 1.1.2 Runs on `admin_action_googlesitekit_proxy_setup` and no longer redirects directly.
	 */
	private function handle_verification_token() {
		$verification_token = $this->context->input()->filter( INPUT_GET, 'googlesitekit_verification_token', FILTER_SANITIZE_STRING );
		$verification_type  = $this->context->input()->filter( INPUT_GET, 'googlesitekit_verification_token_type', FILTER_SANITIZE_STRING );
		$verification_type  = $verification_type ?: self::VERIFICATION_TYPE_META;

		if ( empty( $verification_token ) ) {
			return;
		}

		switch ( $verification_type ) {
			case self::VERIFICATION_TYPE_FILE:
				$this->authentication->verification_file()->set( $verification_token );
				break;
			case self::VERIFICATION_TYPE_META:
				$this->authentication->verification_meta()->set( $verification_token );
		}

		add_filter(
			'googlesitekit_proxy_setup_url_params',
			function ( $params ) use ( $verification_type ) {
				return array_merge(
					$params,
					array(
						'verify'              => 'true',
						'verification_method' => $verification_type,
					)
				);
			}
		);
	}

Here’s a look at the verification request sent during the process:
/wp-admin/index.php?action=googlesitekit_proxy_setup&googlesitekit_code=[SITEKIT-CODE]&googlesitekit_verification_token=[VERIFICATION TOKEN]&googlesitekit_verification_token_type=FILE&nonce=[NONCE]

This was fixed in the latest version with a capability check added on the handle_verification_token function to verify that a verification request occurred during a legitimate authenticated session with a user that had administrative permissions to SETUP the Site Kit by Google plugin.

		if ( ! current_user_can( Permissions::SETUP ) ) {
			wp_die( esc_html__( 'Sorry, you are not allowed to do that.', 'google-site-kit' ), 403 );
		}

These two flaws made it possible for subscriber-level users to become Google Search Console owners on any affected site.

The Impact

When a new owner for a property in Google Search Console is set up, a message is sent via email saying, “Property owners can change critical settings that affect how Google Search interacts with your site or app.”

There are several ways an attacker could make use of Google Search Console owner access for a site. For malicious attackers, the ability to manipulate search engine result pages through Blackhat SEO is particularly attractive. Additionally, an attacker could use search console access in conjunction with another exploit that involves malicious content being injected on a site for monetization.

An owner in Google Search Console can do things like request that URLs be removed from the Google Search engine, view competitive performance data, modify sitemaps, and more.

Unwarranted Google Search Console owner access on a site has the potential to hurt the visibility of a site in Google search results and impact revenue as an attacker removes URLs from search results. More specifically, it could be used to aid a competitor who wants to hurt the ranking and reputation of a site to better improve their own reputation and ranking.

Verifying the Integrity of Google Search Console Ownership

Fortunately, there are ways to verify and monitor if any new Google Search Console owners have been added and the Wordfence firewall provides your site with protection.

As our site cleaning team often sees malicious property owners in Google Search Console added to hacked sites, we’ve included some guidance from them.

Monitoring

Google will alert you via email whenever a new Search Console owner has been added. If you receive one of these emails and have not recently added a new Google Search Console owner, take immediate action and remove the unknown owner.

Verifying and Removing Unwanted Owners

Even if you haven’t received any emails from Google alerting you to the presence of a new Google Search Console owner, you can verify owners from the Google Search Console dashboard.

Checking for Google Search Console users:

  1. Log into your Google Search Console and go to “Settings.” This is where you will find “Users and Permissions.”

    Google Search Console settings location.

  2. Click on “Users and Permissions.” You will see a list of all the Google Search Console users with their name, email address, and role.
  3. Review the users listed. Verify that there are no unknown owners listed.

If you do discover a rogue Google Search Console owner, please take the following actions:

  1. Click the three dots next to the site owner you would like to remove.

    Removing owner.

  2. Click on “Manage property Owners.” Here you can see a log of verification requests and can determine when owners were added, along with the ability to unverify any site owners.

    Managing property owners.

  3. Click “Unverify” for any rogue owner you would like to remove. This will un-verify that account and revoke access to the search console account.

    Un-verifying site owner.

Extra Precaution

Site Kit by Google provides functionality to reset a site’s connection with Site Kit. If you discover that a rogue Google Search Console owner has been added, then we recommend taking the extra step to reset Site Kit by Google on your WordPress site.

Resetting Site Kit by Google:

  1. Log into your WordPress site, and navigate to the Site Kit by Google’s “Settings.”

    Site Kit by Google settings.

  2. Navigate to “Admin Settings” and click on “Reset Site Kit.” Confirm the reset by clicking on “Reset” when prompted. This will reset your Site Kit connection and require you to reconnect any Google services that were previously connected.

    Resetting Site Kit by Google.

Wordfence is Keeping you Protected.

We released a firewall rule on April 21, 2020 to Wordfence Premium users that will block any verification attempts that do not come from administrators, which ultimately provides protection against the creation of any unwarranted Google Search Console owners.

Due to some limitations, the firewall cannot prevent the ProxySetupURL from being displayed in the source code. However, the firewall rule blocking verification requests is enough to provide optimal protection on a site using a vulnerable version of Site Kit by Google.

Free Wordfence users will receive this rule on May 21, 2020.

Proof of Concept Walkthrough

Disclosure Timeline

April 21, 2020 – Initial discovery and analysis of vulnerability. Firewall rule was released for Wordfence Premium customers. We submitted the vulnerability disclosure through Google’s Vulnerability Reward Program, as this appears to be their primary vulnerability disclosure channel.
April 22, 2020 – The vulnerability report was triaged and assigned by the Google Security team.
April 30, 2020 – The Google Security team notifies us that the vulnerability was verified and a bug was filed.
May 4, 2020A commit appears in Site Kit by Google Github Repository that appears to provide a patch for the vulnerability.
May 7, 2020A patch was released.
May 21, 2020 – Free Wordfence users receive firewall rule.

Conclusion

In today’s post, we detailed a flaw that allowed low-level WordPress users the ability to become a Google Search Console owner by exploiting a vulnerability in the Site Kit by Google plugin. This flaw has been fully patched in version 1.8.0. We recommend that users immediately update to the latest version available.

Sites running Wordfence Premium have been protected from attacks against this vulnerability since April 21, 2020. Sites running the free version of Wordfence will receive this firewall rule update on May 21, 2020. If you know a friend or colleague using this plugin on their site, we strongly recommend forwarding this advisory to them so that they can update and protect their Google Search Console account and WordPress site.

The post Vulnerability in Google WordPress Plugin Grants Attacker Search Console Access appeared first on Wordfence.

Read More

Vulnerabilities Patched in Page Builder by SiteOrigin Affects Over 1 Million Sites

On Monday, May 4, 2020, the Wordfence Threat Intelligence team discovered two vulnerabilities present in Page Builder by SiteOrigin, a WordPress plugin actively installed on over 1,000,000 sites. Both of these flaws allow attackers to forge requests on behalf of a site administrator and execute malicious code in the administrator’s browser. The attacker needs to trick a site administrator into executing an action, like clicking a link or an attachment, for the attack to succeed.

We first contacted the plugin developer on May 4, 2020. After establishing an appropriate communication channel, we provided the full disclosure later that day. The developer quickly released a patch the next day, which was May 5, 2020.

These are considered high-risk security issues that could lead to full site takeover. We recommend an immediate update of Page Builder by SiteOrigin to the latest version available. At the time of writing, that is version 2.10.16.

Both the free and Premium version of the Wordfence firewall protect against these vulnerabilities via the built in cross site scripting (XSS) protection in the Wordfence firewall.

Description: Cross-Site Request Forgery to Reflected Cross-Site Scripting
Affected Plugin: Page Builder by SiteOrigin
Plugin Slug: siteorigin-panels
Affected Versions: <= 2.10.15
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 2.10.16

Page Builder by SiteOrigin is a plugin that simplifies page and post editing in WordPress. Users can create “responsive column based content” using both widgets from WordPress and widgets from the SiteOrigin Widgets Bundle plugin.

The plugin has a built-in live editor so users can update content and drag/drop widgets while observing those changes made in real time. This makes the editing and designing for a page or post a much smoother process.

A view of the Page Builder by SiteOrigin live editor feature.

In order to show the modifications in real time through the live editor, the plugin registers the is_live_editor() function to check if a user is in the live editor.

static function is_live_editor(){
  return ! empty( $_GET['siteorigin_panels_live_editor'] );
}

If the user is in the live editor, the siteorigin_panels_live_editor parameter will be set to “true” and register that a user is accessing the live editor. The plugin will then attempt to include the live editor file which renders all of the content.

	// Include the live editor file if we're in live editor mode.
		if ( self::is_live_editor() ) {
			SiteOrigin_Panels_Live_Editor::single();
		}

Any content changes made are set and sent as a $_POST parameter:  live_editor_panels_data.  This parameter contains all of the content that has been edited by the user and is required to render a live preview of the changes.

Once a change has been made, the live-editor-preview.php file is used to render the content provided from the live_editor_panels_data parameter and update the page preview displaying any changes made changes in real-time.

 <?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } wp_enqueue_style( 'siteorigin-preview-style', siteorigin_panels_url( 'css/live-editor-preview' . SITEORIGIN_PANELS_CSS_SUFFIX . '.css' ), array(), SITEORIGIN_PANELS_VERSION ); ?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="profile" href="http://gmpg.org/xfn/11">
	<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
	<?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
	
<div id="content" class="site-content">
		
<div class="entry-content">
			<?php if( !empty( $_POST['live_editor_panels_data'] ) ) { $data = json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true ); if( !empty( $data['widgets'] ) && ( !class_exists( 'SiteOrigin_Widget_Field_Class_Loader' ) || method_exists( 'SiteOrigin_Widget_Field_Class_Loader', 'extend' ) ) ) { $data['widgets'] = SiteOrigin_Panels_Admin::single()->process_raw_widgets( $data['widgets'], false, false );
				}
				echo siteorigin_panels_render( 'l' . md5( serialize( $data ) ), true, $data);
			}
			?>
		</div>

<!-- .entry-content -->
	</div>

	<?php wp_footer(); ?>
</body>
</html>

While capability checks were present in the post_metadata function to ensure a user accessing the live editor was allowed to edit posts, there was no nonce protection to verify that an attempt to render content in the live editor came from an legitimate source.

	function post_metadata( $value, $post_id, $meta_key ) {
		if (
			$meta_key == 'panels_data' &&
			current_user_can( 'edit_post', $post_id ) &&
			! empty( $_POST['live_editor_panels_data'] ) &&
			$_POST['live_editor_post_ID'] == $post_id
		) {
			$value = array( json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true ) );
		}
		return $value;
	}

As part of this exploit, some of the available widgets, such as the “Custom HTML” widget, could be used to inject malicious JavaScript into a rendered live page. If a site administrator was tricked into accessing a crafted live preview page, any malicious Javascript included as part of the “Custom HTML” widget could be executed in the browser. The data associated with a live preview was never stored in the database, resulting in a reflected XSS flaw rather than stored XSS flaw, in conjunction with the CSRF flaw.

This flaw could be used to redirect a site’s administrator, create a new administrative user account, or, as seen in the recent attack campaign targeting XSS vulnerabilities, be used to inject a backdoor on a site.

Description: Cross-Site Request Forgery to Reflected Cross-Site Scripting
Affected Plugin: Page Builder by SiteOrigin
Plugin Slug: siteorigin-panels
Affected Versions: <= 2.10.15
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 2.10.16

We discovered an additional Cross-Site Request Forgery flaw in the action_builder_content function of the plugin. This was tied to the AJAX action wp_ajax_so_panels_builder_content.

add_action( 'wp_ajax_so_panels_builder_content', array( $this, 'action_builder_content' ) );

This function’s purpose was to transmit content submitted as panels_data from the live editor to the WordPress editor in order to update or publish the post using the content created from the live editor. This function did have a permissions check to verify that a user had the capability to edit posts for the given post_id. However, there was no nonce protection to verify the source of a request, causing the CSRF flaw.

	/**
	 * Get builder content based on the submitted panels_data.
	 */
	function action_builder_content() {
		header( 'content-type: text/html' );

		if ( ! current_user_can( 'edit_post', $_POST['post_id'] ) ) {
			wp_die();
		}

As part of the process, the content from the panels_data function was purposefully retrieved so that could be echoed to the page.

if ( empty( $_POST['post_id'] ) || empty( $_POST['panels_data'] ) ) {
			echo '';
			wp_die();
		}

		// echo the content
		$old_panels_data        = get_post_meta( $_POST['post_id'], 'panels_data', true );
		$panels_data            = json_decode( wp_unslash( $_POST['panels_data'] ), true );
		$panels_data['widgets'] = $this->process_raw_widgets(
			$panels_data['widgets'],
			! empty( $old_panels_data['widgets'] ) ? $old_panels_data['widgets'] : false,
			false
		);
		$panels_data            = SiteOrigin_Panels_Styles_Admin::single()->sanitize_all( $panels_data );

With this function, the “Custom HTML” widget did not create an XSS flaw in the same way as the previous vulnerability due to some sanitization features. However, we discovered that the “Text” widget could be used to inject malicious JavaScript due to the ability to edit content in a ‘text’ mode rather than a ‘visual’ mode. This allowed potentially malicious JavaScript to be sent unfiltered. Due to the widget data being echoed, any malicious code that was a part of the text widgets data could then be executed as part of a combined CSRF to XSS attack in a victim’s browser.

As with the previously mentioned CSRF to Reflected XSS vulnerability, this could ultimately be used to redirect a site’s administrator, create a new administrative user account, or, as seen in the recent attack campaign targeting XSS vulnerabilities, be used to inject a backdoor on a site.

Proof of Concept Walkthrough

Disclosure Timeline

May 4, 2020 – Initial discovery and analysis of vulnerabilities. We verify the Wordfence built-in XSS firewall rule offers sufficient protection. Initial outreach to the plugin’s team.
May 4, 2020 – Plugin’s developer confirms appropriate channel and we provide full disclosure.
May 5, 2020 – Developer acknowledges vulnerabilities and advises that they should have a patch released later in the day.
May 5, 2020 – A sufficient patch is released.

Conclusion

In today’s post, we detailed two flaws present in the Page Builder by SiteOrigin plugin that allowed attackers to forge requests on behalf of a site administrator and execute malicious code in that administrator’s browser. These flaws have been fully patched in version 2.10.16. We recommend that users immediately update to the latest version available.

Sites running Wordfence Premium, as well as sites using the free version of Wordfence, are protected from Cross-Site Scripting attacks against this vulnerability due to the Wordfence firewall’s built-in protection. If you know a friend or colleague who is using this plugin on their site, we highly recommend forwarding this advisory to them to help keep them protected.

Special thanks to Greg Priday, the plugin’s developer, for an extremely prompt response and for releasing a patch very quickly.

The post Vulnerabilities Patched in Page Builder by SiteOrigin Affects Over 1 Million Sites appeared first on Wordfence.

Read More

Combined Attack on Elementor Pro and Ultimate Addons for Elementor Puts 1 Million Sites at Risk

On May 6, 2020, our Threat Intelligence team received reports of active exploitation of vulnerabilities in two related plugins, Elementor Pro and Ultimate Addons for Elementor. We have reviewed the log files of compromised sites to confirm this activity.

As this is an active attack, we wanted to alert you so that you can take steps to protect your site. We are intentionally limiting the amount of information this post provides, because this is an ongoing attack, and the most critical vulnerability has not yet been patched.

We have released a firewall rule which protects Wordfence Premium users against exploitation of this vulnerability. Free Wordfence users will be protected against this vulnerability after 30 days, on June 5, 2020.

Which plugins are affected by this attack

There are two plugins affected by this attack campaign. The first is Elementor Pro which is made by Elementor. This plugin has a zero day vulnerability which is exploitable if users have open registration.

The second affected plugin is Ultimate Addons for Elementor, which is made by Brainstorm Force. A vulnerability in this plugin allows the Elementor Pro vulnerability to be exploited, even if the site does not have user registration enabled.

We estimate that Elementor Pro is installed on over 1 million sites and that Ultimate Addons has an install base of roughly 110,000.

Elementor Pro

To be clear, this does not impact the free Elementor plugin with over 4 million installations available from the WordPress plugin repository. The Elementor Pro plugin is a separate download available from the Elementor.com website. We estimate that Elementor Pro has over 1 million active installations.

The vulnerability in Elementor Pro, which is rated Critical in severity, allows registered users to upload arbitrary files leading to Remote Code Execution. This is a zero day vulnerability.

An attacker able to remotely execute code on your site can install a backdoor or webshell to maintain access, gain full administrative access to WordPress, or even delete your site entirely. Due to the vulnerability being unpatched at this time, we are excluding any further information.

We have data via another vendor that indicates the Elementor team are working on a patch. We have contacted Elementor and did not immediately receive confirmation of this before publication.

Ultimate Addons for Elementor

The Ultimate Addons for Elementor plugin recently patched a vulnerability in version 1.24.2 that allows attackers to create subscriber-level users, even if registration is disabled on a WordPress site.

Two vulnerabilities being used in concert to attack sites

Attackers are able to directly target the zero day vulnerability in Elementor Pro on sites with open user registration.

In cases where a site does not have user registration enabled, attackers are using the Ultimate Addons for Elementor vulnerability on unpatched sites to register as a subscriber. Then they proceed to use the newly registered accounts to exploit the Elementor Pro zero day vulnerability and achieve remote code execution.

What you should do

If you are using Wordfence Premium, your site has received a firewall rule to protect you against this active attack.

There are a number of steps a site owner not using Wordfence Premium can take to protect their site from this active attack.

Upgrade Ultimate Addons for Elementor immediately. Make sure Ultimate Addons for Elementor is version 1.24.2 or greater.

Downgrade to Elementor free until a patch is released for Elementor Pro. You can do so by deactivating Elementor Pro and removing it from your site. This will remove the file upload vulnerability.

Once a patch is released, you can re-install the patched version of Elementor Pro on your site and regain any lost functionality. You may temporarily lose some design elements once downgraded, but in our tests these elements came back when reinstalling Elementor Pro. Nevertheless, a backup prior to downgrading is always prudent.

Tip: If you need a list of where you have Elementor Pro installed, you can login to your account on Elementor.com and go to “Purchases” then “View Websites” for a full list where Elementor Pro is installed with that license.

Check for any unknown subscriber-level users on your site. This may indicate that your site has been compromised as a part of this active campaign. If so, remove those accounts.

Check for files named “wp-xmlrpc.php.” These can be considered an indication of compromise, so check your site for evidence of this file. Wordfence will alert you if a file containing malware is found.

Delete any unknown files or folders found in /wp-content/uploads/elementor/custom-icons/ directory. Files located here after a rogue subscriber-level account has been created are a clear indication of compromise.

If you are seeing widespread infection, use Wordfence to clean your site. The linked guide will assist you, or you can engage our Security Services Team for a professional site cleaning. As always, premium customers have access to our customer support engineers if there are any questions.

Thank you to Customer Service Engineer Gerroald Barron for bringing this issue to our attention, as well as Stephen Rees-Carter, Ramuel Gall, and Kathy Zant for their assistance in researching this attack and testing mitigations.

The post Combined Attack on Elementor Pro and Ultimate Addons for Elementor Puts 1 Million Sites at Risk appeared first on Wordfence.

Read More

28,000 GoDaddy Hosting Accounts Compromised

This is a public service announcement (PSA) from the Wordfence team regarding a security issue which may impact some of our customers. On May 4, 2020, GoDaddy, one of the world’s largest website hosting providers, disclosed that the SSH credentials of approximately 28,000 GoDaddy hosting accounts were compromised by an unauthorized attacker.

SSH, while extremely secure if configured correctly, can allow logins with either a username/password combination, or a username and a public/private key pair. In the case of this breach, it appears likely that an attacker placed their public key on the affected accounts so that they could maintain access even if the account password was changed.

It is unclear which of GoDaddy’s hosting packages were affected by this breach. According to GoDaddy’s public statement:

“On April 23, 2020, we identified SSH usernames and passwords had been compromised by an unauthorized individual in our hosting environment. This affected approximately 28,000 customers. We immediately reset these usernames and passwords, removed an authorized SSH file from our platform, and have no indication the individual used our customers’ credentials or modified any customer hosting accounts. The individual did not have access to customers’ main GoDaddy accounts.”

The breach itself appears to have occurred on October 19, 2019.

What should I do?

Immediate Action

If you have been impacted by this breach and have not already been notified by GoDaddy, you will likely be notified in the near future.

GoDaddy indicates that they have updated the account passwords and removed the attacker’s public key. While this should prevent the attacker from accessing impacted sites via SSH, we strongly recommend changing your site’s database password, as this could have easily been compromised by an attacker without modifying the account.

Compromised database credentials could be used to gain control of a WordPress site if remote database connections are enabled, which GoDaddy allows on many of its hosting accounts. You may also wish to check your site for unauthorized administrative users, as these could have been created without modifying any files on the site.

Remain Vigilant

Breaches like this can create a prime target for attackers who use phishing campaigns as a means to infect users.

Phishing, by general definition, is an attack whereby an attacker will create an email that appears to come from a legitimate source, but is intended to obtain sensitive information from an unsuspecting user. Although only 28,000 hosting accounts appear to have been affected, it is estimated that millions of sites are hosted by GoDaddy. This means that there are millions of users out there who might be worried that they will receive a notification that their hosting account has been breached.

Therefore the likelihood of a phishing campaign targeting GoDaddy users is high. We recommend that under these conditions, GoDaddy customers take care when clicking on links or executing any actions in an email to ensure that they don’t end up as the victim of a phishing attack.

There are a few key things you can check to see if you are the target of a phishing attack:

  • Check the email header. If the source of the email does not come from a registered GoDaddy domain, then it most likely did not come from GoDaddy and is an attempt at phishing.
  • Look for a large amount of typos or misspellings in the email content itself. This can indicate the presence of an attacker. Professional emails will contain minimal typos or misspellings, if any.
  • Modified verbiage used to scare you into providing personal information. GoDaddy’s security incident disclosure email should not appear to scare you, or ask you to provide any information. It should simply inform you that you may have been impacted by a breach. If you receive an email that appears to be scaring you into providing information, then it may be a phishing attempt.

If you can not verify the source of an email or its legitimacy, it is best to go directly to the GoDaddy site and contact them via their standard support channels. This will allow you to verify that your account is secure.

This is a public service announcement by the Wordfence Threat Intelligence team. We are providing this as a courtesy to our own customers, and to the larger WordPress community. Please contact GoDaddy directly if you have questions about the breach or about the security of your account. If you have friends or colleagues who use GoDaddy hosting, we suggest that you share this post with them to ensure they are aware of this issue.

Thank you to Wordfence Senior QA Engineer Ram Gall for his joint contributions and research to this post.

The post 28,000 GoDaddy Hosting Accounts Compromised appeared first on Wordfence.

Read More

High Severity Vulnerability Patched in Real-Time Find and Replace Plugin

On April 22, 2020, our Threat Intelligence team discovered a vulnerability in Real-Time Find and Replace, a WordPress plugin installed on over 100,000 sites. This flaw could allow any user to inject malicious Javascript anywhere on a site if they could trick a site’s administrator into performing an action, like clicking on a link in a comment or email.

We reached out to the plugin developer on April 22, 2020, and they released a patch just a few hours after we disclosed the vulnerability to them. This is considered a high-severity security issue, therefore we strongly recommend an immediate update to the latest version available, which at the time of writing is version 4.0.2.

Both Wordfence Premium and Free Wordfence users are protected from XSS attempts against this vulnerability by the Wordfence firewall’s built-in XSS protection.

Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
Affected Plugin: Real-Time Find and Replace
Plugin Slug: real-time-find-and-replace
Affected Versions: <= 3.9
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Fully Patched Version: 4.0.2

Real-Time Find and Replace provides functionality to dynamically replace any HTML content on WordPress sites with new content without permanently changing the source content. The replacement data loads immediately before it is delivered to the user’s browser. The plugin is very easy to use due to its limited functionality.

To provide this functionality, the plugin registers a sub-menu page tied to the function far_options_page with a capability requirement to “activate_plugins.”

 function far_add_pages() {
	$page = add_submenu_page( 'tools.php', 'Real-Time Find and Replace', 'Real-Time Find and Replace', 'activate_plugins', 'real-time-find-and-replace', 'far_options_page' );
	add_action( "admin_print_scripts-$page", "far_admin_scripts" );

The far_options_page function contains the core of the plugin’s functionality for adding new find and replace rules. Unfortunately, that function failed to use nonce verification, so the integrity of a request’s source was not verified during rule update, resulting in a Cross-Site Request Forgery vulnerability.

function far_options_page() {    
	if ( isset( $_POST['setup-update'] ) ) {
		$_POST = stripslashes_deep( $_POST );
		
		// If atleast one find has been submitted
		if ( isset ( $_POST['farfind'] ) && is_array( $_POST['farfind'] ) ) { 
			foreach ( $_POST['farfind'] as $key => $find ){

Any attacker capable of tricking a site owner into executing an unwanted action could replace any content or HTML on a vulnerable site with new content or malicious code. This replacement code or content would then execute anytime a user navigated to a page that contained the original content.

An attacker could use this vulnerability to replace a HTML tag like <head> with malicious Javascript. This would cause the malicious code to execute on nearly every page of the affected site, as nearly all pages start with a <head> HTML tag for the page header, creating a significant impact if successfully exploited. The malicious code could be used to inject a new administrative user account, steal session cookies, or redirect users to a malicious site, allowing attackers the ability to obtain administrative access or to infect innocent visitors browsing a compromised site.

Example of <head> HTML tag being replaced with Javascript.

In the most up to date version, a nonce has been added along with a check_admin_referer nonce verification function to ensure the legitimacy of the source of a request.

function far_options_page() {    
	if ( isset( $_POST['setup-update'] ) ) {
        check_admin_referer( 'far_rules_form' );
		$_POST = stripslashes_deep( $_POST );
		
		// If atleast one find has been submitted
		if ( isset ( $_POST['farfind'] ) && is_array( $_POST['farfind'] ) ) { 
			foreach ( $_POST['farfind'] as $key => $find ){

Disclosure Timeline

April 22, 2020 – Initial discovery and analysis of vulnerability. We verify the Wordfence built-in XSS firewall rule is sufficient. Initial outreach to plugin developer.
April 22, 2020 8:51 AM UTC – Developer responds confirming appropriate inbox.
April 22, 2020 9:34 AM UTC – We provide the full disclosure.
April 22, 2020 1:30 PM UTC – We receive notification that patch has been released.

Conclusion

In today’s post, we detailed a Cross-Site Request Forgery flaw in the Real-Time Find and Replace plugin. This flaw has been fully patched in version 4.0.2. We recommend that users update to the latest version, which is available immediately. Sites running Wordfence Premium, as well as sites using the free version of Wordfence, are protected from Cross-Site Scripting attacks against this vulnerability due to the Wordfence firewall’s built-in protection. If you are aware of a friend or colleague using this plugin, we recommend you forward this security advisory to them as soon as possible to help secure their site.

The post High Severity Vulnerability Patched in Real-Time Find and Replace Plugin appeared first on Wordfence.

Read More

Vulnerability Patched in Accordion Plugin

A few weeks ago, our Threat Intelligence team discovered a vulnerability in Accordion, a WordPress plugin installed on over 30,000 sites. This flaw allowed any authenticated user with subscriber-level and above permissions the ability to import a new accordion and inject malicious Javascript as part of the accordion.

We initially reached out to the plugin’s developer on March 10, 2020, however, an appropriate communication channel was not established until March 18, 2020. A patch was released just 3 hours after full disclosure.

This is considered a medium-level security issue that could potentially lead to attackers completely taking over WordPress sites. We highly recommend an immediate update to the latest version available, 2.2.15.

Wordfence Premium customers received a new firewall rule on March 10, 2020, to protect against exploits targeting this vulnerability. Free Wordfence users received this rule after thirty days, on April 9, 2020.

Description: Unprotected AJAX Action to Stored/Reflected Cross-Site Scripting (XSS)
Affected Plugin: Accordion
Plugin Slug: accordions
Affected Versions: <= 2.2.7
CVE ID: Will be updated once identifier is supplied.
CVSS Score: 5.4 (Medium)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Fully Patched Version: 2.2.9

The Accordion plugin is a relatively simple plugin used to create accordion style FAQ pages and knowledge base areas on WordPress sites. As part of the plugin’s functionality, users can import new accordions, so that accordions can be exported on one site and migrated to another or even used to restore accordion backups.

In order to provide this functionality, the plugin registers an AJAX action that is used to register the import of a JSON file and its contents as a new accordion.

add_action('wp_ajax_accordions_ajax_import_json', 'accordions_ajax_import_json');
//add_action('wp_ajax_nopriv_accordions_ajax_import_json', 'accordions_ajax_import_json');

This action is hooked to the function accordions_ajax_import_json where the data from the JSON file is extracted, analyzed, and used to create a new post with the post_type set to ‘accordions.’

function accordions_ajax_import_json(){

	$response = array();
	$json_file = isset($_POST['json_file']) ? $_POST['json_file'] : '';
	$string = file_get_contents($json_file);
	$json_a = json_decode($string,true);


	foreach ($json_a as $post_id=>$post_data){

	    $meta_fields = $post_data['meta_fields'];
		$title = $post_data['title'];

		// Create post object
		$my_post = array(
			'post_title'    => $title,
			'post_type' => 'accordions',
			'post_status'   => 'publish',

		);

		$post_inserted_id = wp_insert_post( $my_post );

		foreach ($meta_fields as $meta_key=>$meta_value){
			update_post_meta( $post_inserted_id, $meta_key, $meta_value );
        }




    }


	$response['json_a'] = $json_a;
	//$response['string'] = $string;
	//$response['json_file'] = $json_file;




	echo json_encode( $response );



	die();
}

Due to the lack of capability checks and the inherent ability of any user logged in to a WordPress site to execute AJAX actions, this meant that any authenticated user, including those with minimal permissions, could import a new accordion from a remotely hosted JSON file. Additionally, malicious Javascript could be included in the imported accordion, allowing an attacker to inject malicious code that would execute if an administrator accessed the imported accordion from the WordPress administrative dashboard. This is considered to be a Stored Cross-Site Scripting vulnerability.

Alternatively, an attacker could exploit this weakness by tricking a site owner into clicking on a link designed to import a specially crafted JSON file containing malicious Javascript.
As shown in the accordions_ajax_import_json function, the JSON file’s contents are decoded at the start of the import and later echoed at the end of a successful import causing any malicious Javascript that was contained in the file to be executed in the victim’s browser. This is considered to be a Reflected Cross-Site Scripting vulnerability.

If an attacker was able to successfully trick an administrator into accessing their maliciously uploaded accordion or clicking on a specially crafted link, they could obtain an administrative user account, redirect the site owner to a malicious site, or steal session cookies to authenticate onto the site on behalf of the administrator. This meant an attacker could completely take over a vulnerable site by exploiting these XSS flaws.

This function was also vulnerable to Cross-Site Request Forgery (CSRF) due to the lack of a WordPress nonce and corresponding verification.

Fortunately, in the most up-to-date versions of this plugin, there is a nonce and capability check present for the accordions_ajax_import_json function as shown below:

function accordions_ajax_import_json(){

	$response = array();


    $nonce = isset($_POST['nonce']) ? sanitize_text_field($_POST['nonce']) : '';
    if(wp_verify_nonce( $nonce, 'accordions_nonce' )) {

        if(current_user_can( 'manage_options' )){

            $json_file = isset($_POST['json_file']) ? $_POST['json_file'] : '';
            $string = file_get_contents($json_file);
            $json_a = json_decode($string,true);

Disclosure Timeline

March 10, 2020 – Initial discovery and analysis of vulnerability. Firewall rule was released for Wordfence Premium customers. We made our initial contact attempt with the plugin development team.
March 18, 2020 – An appropriate communication channel was established and full disclosure details were sent. Patch was released just 3 hours after disclosure.
April 9, 2020 – Free Wordfence users received firewall rule.

Conclusion

In today’s post, we detailed a flaw related to an unprotected AJAX action that allowed for malicious accordions to be imported in Accordion, a WordPress plugin. This flaw has been fully patched in version 2.2.9. We recommend that users immediately update to the latest version available. Sites running Wordfence Premium have been protected from attacks against this vulnerability since March 10, 2020. Sites running the free version of Wordfence received this firewall rule update on April 9, 2020.

The post Vulnerability Patched in Accordion Plugin appeared first on Wordfence.

Read More

Vulnerabilities Patched in the Data Tables Generator by Supsystic Plugin

A few weeks ago, we disclosed several flaws that were patched in the Pricing Table by Supsystic plugin. On January 20th, our Threat Intelligence team discovered several similar vulnerabilities present in another product from Supsystic: Data Tables Generator by Supsystic, a WordPress plugin installed on over 30,000 sites. These flaws were very similar and allowed an attacker to execute several AJAX actions, inject malicious Javascript, and forge requests on behalf of an authenticated site user. However, in the Data Tables Generator plugin, these flaws required an attacker to be logged in as a user with subscriber or above permissions on a target site.

We privately disclosed these issues to the plugin’s author at the same time we fully disclosed the flaws discovered in Pricing Table by Supsystic; again, they released patches a little over a month later. We recommend updating to the latest version, 1.9.92, immediately.

Wordfence Premium users received a new firewall rule on January 21, 2020 to protect against exploits targeting these vulnerabilities. Free Wordfence users received this rule on February 20, 2020.


Description: Insecure Permissions on AJAX Actions
Affected Plugin: Data Tables Generator by Supsystic
Plugin Slug: data-tables-generator-by-supsystic
Affected Versions: <= 1.9.91
CVE ID: Post will be updated once assigned.
CVSS Score: 6.3 (Medium)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Patched Version: 1.9.92

Data Tables Generator by Supsystic is an easy to use responsive table, chart, and data management plugin. It has several features such as custom css, the ability to add iframes, different fonts and label capabilities, and more. Unfortunately, we discovered that all of the AJAX actions to provide these features lacked capability checks and WordPress nonces for CSRF (Cross-Site Request Forgery) protection.

</pre>
<pre> /**
  * Validate and creates the new table.
  * @param Rsc_Http_Request $request
  * @return Rsc_Http_Response
  */
 public function createAction(Rsc_Http_Request $request)
 {
     $title = trim($request->post->get('title'));
     $rowsCount = (int) $request->post->get('rows');
     $colsCount = (int) $request->post->get('cols');

     try {
if (!$this->isValidTitle($title)) {
             return $this->ajaxError($this->translate('Title can\'t be empty or more than 255 characters'));
         }
$this->getEnvironment()->getModule('tables')->setIniLimits();
// Add base settings
         $tableId = $this->getModel('tables')->add(array('title' => $title, 'settings' => serialize(array())));

if($tableId) {
   $rows = array();

   for($i = 0; $i < $rowsCount; $i++) {
      array_push($rows, array('cells' => array()));
      for($j = 0; $j < $colsCount; $j++) {
         array_push($rows[$i]['cells'], array(
            'data' => '',
            'calculatedValue' => '',
                         'hidden' => '',
                      'type' => 'text',
                      'formatType' => '',
            'meta' => array()
         ));
      }
   }
   // Save an empty table's rows to prevent error when the Data Tables script will be executed
   $this->getModel('tables')->setRows($tableId, $rows);
}
     } catch (Exception $e) {
         return $this->ajaxError($e->getMessage());
     }

     return $this->ajaxSuccess(array('url' => $this->generateUrl('tables', 'view', array('id' => $tableId))));
 }</pre>
<pre>

**One example of a function triggered by the AJAX action create. No nonce or permission checks present.

WordPress AJAX actions can be processed by any authenticated user. As such, AJAX actions should always require an additional capability check in order to verify that the user sending the request is an authenticated administrative user when the action is meant for only administrative users. Without the required permission check, any user logged in as subscriber or above could execute the actions and make malicious changes to any given data table, or create a new data table. With many sites allowing open subscriber registrations, protecting site functionality with capability checks is critical when utilizing AJAX actions.

The vulnerable endpoints we discovered were: getListForTbl, updateRows, updateMeta, saveSettings, remove, create, render, getSettings, getMeta, getCountRows, getRows, clone, and rename. The most impactful endpoints were rename, where an attacker could rename any given data table name, getListForTbl, where an attacker could discover all of the existing tables and use that information to craft a request, saveSettings, where an attacker could modify any data table settings maliciously, and create, where an attacker could create a new data table with any options set.


Description: Authenticated Stored XSS
Affected Plugin: Data Tables Generator by Supsystic
Affected Versions: <= 1.9.91
CVE ID: Post will be updated once assigned.
CVSS Score: 5.4 (Medium)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Patched Version: 1.9.92

As an extension of the previous vulnerability, we discovered that malicious Javascript could be injected into many data table fields, including the title, the data table cells, the description and caption, and more, by using the saveSettings endpoint to update an existing data table.

The malicious Javascript would then execute in a site visitor’s browser whenever they accessed a page containing the data table. This could ultimately lead to malicious site redirection, new administrative user account creation, and other malicious actions.

As previously mentioned with the Pricing Table by Supsystic plugin, WordPress allows default administrators the capability to use unfiltered_html. Alone, these settings would not be considered a security risk if only administrative users had access to modify these settings. However, providing the unfiltered_html capability with these AJAX actions that allowed even subscriber-level users to modify these settings introduced a cross site scripting (XSS) vulnerability.


Description: CSRF to Stored XSS, Data Table Creations, Settings Modification
Affected Plugin: Data Tables Generator by Supsystic
Plugin Slug: data-tables-generator-by-supsystic
Affected Versions: <= 1.9.91
CVE ID: Post will be updated once assigned.
CVSS Score: 8.8 (High)
CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Patched Version: 1.9.92

The lack of WordPress nonces for CSRF protection on all actions registered in this plugin also resulted in several Cross-Site Request Forgery (CSRF) vulnerabilities. Given that the registered actions could be executed by any logged-in user regardless of privilege level, CSRF exploit attempts could be targeted towards any user, even those with just a subscriber role.

If an attacker was able to trick any authenticated user into clicking on a link or opening a malicious attachment, a forged request could be sent on behalf of that user to modify any given data table and inject malicious Javascript. Again, the malicious Javascript could inject a new administrative user, redirect site visitors to a malicious site, and more.

It is important to remember not to click on links in comments or emails unless you can verify the authenticity of the source and the destination to protect against a CSRF exploit attempt. It is difficult for firewalls to protect against CSRF attacks because the malicious request appears to come from a valid, authenticated user.

Disclosure Timeline

January 20, 2020 – Vulnerability initially discovered and analyzed. We begin working on firewall rules.
January 21, 2020 – Firewall rule released for Wordfence premium users. Awaiting response from the Supsystic’s plugin team in regards to vulnerabilities in Pricing Table by Supsystic.
January 21, 2020 – Plugin team confirms appropriate inbox for handling discussion. Full disclosure of vulnerabilities is sent.
January 30, 2020 – Follow-up with plugin team as no response from disclosure.
February 11, 2020 – Plugin developer acknowledges report.
February 20, 2020 – Wordfence free users receive firewall rule.
February 21, 2020 – Additional and final follow-up. Insufficient patch released.
February 21 to March 23, 2020 – Back and forth with the plugin team to ensure an optimal solution released.
March 23, 2020 – Final patch released.

Conclusion

In today’s post, we detailed several vulnerabilities including stored XSS, CSRF, and insecure permissions found in the Data Tables by Supsystic plugin. These flaws have been fully patched in version, 1.9.92, and we recommend that users update to the latest version available immediately. Sites running Wordfence Premium have been protected from attacks against this vulnerability since January 21, 2020. Sites running the free version of Wordfence received the firewall rule update on February 20, 2020.

The post Vulnerabilities Patched in the Data Tables Generator by Supsystic Plugin appeared first on Wordfence.

Read More
Page 1 of 3123»