High Priority Vulnerabilities Patched in Uncode Core Plugin

Published 7 May 2024
Updated 15 May 2024
Rafie Muhammad
Security Researcher at Patchstack
Table of Contents

This blog post is about the Uncode Core plugin vulnerabilities. If you're a Uncode user, please update the core plugin to at least version 2.8.9.

All paid Patchstack users are protected from this vulnerability. Sign up for the free Community account first, to scan for vulnerabilities and apply protection for only $5 / site per month with Patchstack.

For plugin developers, we have security audit services and Enterprise API for hosting companies.

About the Uncode Core Plugin

The plugin Uncode Core (premium version) is a required plugin for the Uncode theme. The theme itself has more than 110,000 sales at ThemeForest. The Uncode theme is known as the more popular premium theme for WooCommerce sites. This plugin is developed by Undsgn.

The Uncode theme itself is a pixel-perfect creative WordPress Theme for any kind of website (portfolio, agency, freelance, blog) and a top WooCommerce Theme for shops (eCommerce, online store, business).

The security vulnerabilities

The Uncode Core plugin suffers from multiple vulnerabilities. The first vulnerability is an authenticated arbitrary file and directory deletion which allows any authenticated users with a minimum of Subscriber role to delete arbitrary directories on the server.

The second vulnerability is an authenticated privilege escalation which allows any authenticated user with a minimum of Subscriber role to escalate their privilege to any role on the WordPress site by abusing an insecure WP Option update. The described vulnerabilities were fixed in version 2.8.9 and assigned CVE-2023-51500 and CVE-2023-51515 respectively.

Authenticated Arbitrary File and Directory Deletion

The underlying vulnerable code exists in the delete_download function:

function delete_download() {
	if (isset($_REQUEST['font_family'])) {
		$font_family = $_REQUEST['font_family'];
		$font_dir = trailingslashit($this->font_directory).$font_family;
		$fontkit_zip = $font_dir.'.zip';

		if (@file_exists($fontkit_zip)) {
			if (!@unlink($fontkit_zip)) {
				echo json_encode(array(
					'error' => sprintf( esc_html__( 'Failed to delete @fontface kit zip %1$s.', 'uncode-core' ), $fontkit_zip )
				));
				die();
			}
		}

		// Cannot delete the directory, because unzip_file, which has created it, uses WP_Filesystem. So we use WP_Filesystem to delete it.
		$this->setup_wp_filesystem();

		global $wp_filesystem;
		if (isset($wp_filesystem)) {
			$delete_dir = $wp_filesystem->delete($font_dir, true);
			if (!$delete_dir) {
				echo json_encode(array('error' => $delete_dir['error']));
				die();
			}
		}

		echo json_encode(array('success' => "Download deleted"));
	}
	die();
}

The above function is attached to the wp_ajax_uncodefont_delete_download action, since there is no proper permission and nonce check, any authenticated users are able to execute the function. Notice that the function will perform $wp_filesystem->delete() with $font_dir variable. The $font_dir variable itself is constructed from $font_family variable which is coming from $_REQUEST['font_family'] without proper sanitization. In this case, users are able to perform directory traversal and delete arbitrary directories on the server.

Authenticated Privilege Escalation

The underlying vulnerable code exists in the save_option function:

public function save_option() {
	if ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'uncode-core-settings-nonce' ) ) {
		if ( isset( $_POST['value'] ) && $_POST['value'] && isset( $_POST['option_id'] ) && $_POST['option_id'] ) {
			$autoload = isset( $_POST['autoload'] ) && $_POST['autoload'] === 'true' ? true : false;
			update_option( $_POST['option_id'], $_POST['value'], $autoload );
---------- CUT HERE ----------

The above function is attached to the wp_ajax_uncode_core_settings_update_option action, since there is no proper permission check, any authenticated user is able to hit the function. There is indeed a nonce validation with the action "uncode-core-settings-nonce", however, this nonce value can be retrieved by any authenticated user that has access to the wp-admin area, this is because the nonce is displayed using the admin_scripts function:

public function admin_scripts() {
	$core_settings_parameters = array(
		'enable_debug' => apply_filters( 'uncode_enable_debug_on_js_scripts', false ),
		'nonce'      => wp_create_nonce( 'uncode-core-settings-nonce' ),
		'locale'     => array(
			'button_confirm'  => esc_html__( 'Save', 'uncode-core' ),
		)
	);

	wp_enqueue_script( 'uncode-core-settings', UNCODE_CORE_PLUGIN_URL . 'includes/core-settings/js/uncode-core-settings.js', array( 'jquery' ), UncodeCore_Plugin::VERSION, true );

	wp_localize_script( 'uncode-core-settings', 'CoreSettingsParameters', $core_settings_parameters );
}

Notice that also the function will call the update_option function and will set the option key and value directly from $_POST['option_id'] and $_POST['value']. Since users can arbitrarily set the option key and value to update, users can simply do a privilege escalation by enabling the user registration feature on the WordPress site and setting the default role of registration to Administrator role.

The patch

For the Authenticated Arbitrary File and Directory Deletion vulnerability, the vendor decided to apply a permission and nonce check to the function without sanitizing the affected variable. The patch can be seen below:

For the Authenticated Privilege Escalation vulnerability, the vendor decided to apply a permission and nonce check to the function allowing with a whitelist check on what option key can be updated. The patch can be seen below:

Conclusion

For every Ajax action that involves sensitive actions, please always secure it by implementing permission and nonce checks. Only implementing a nonce validation as a check most of the time can be bypassed if the nonce value can be retrieved by unauthorized users such as lower permission role users.

Always do a sanitization or whitelist check on user input that is used to construct a file or directory path and also always limit what option key can be updated on certain actions.

Timeline

24 August, 2023We found the vulnerabilities and reached out to the plugin vendor.
28 August, 2023vPatches deployed to protect our customers.
22 November, 2023Uncode theme alongside Uncode Core plugin version 2.8.9 released to patch the reported issues.
21 December, 2023Added the vulnerabilities to the Patchstack vulnerability database.
07 May, 2024Security advisory article published.

Help us make the Internet a safer place

Making the WordPress ecosystem more secure is a team effort, and we believe that plugin developers and security researchers should work together.

  • If you're a plugin developer, join our mVDP program that makes it easier to report, manage and address vulnerabilities in your software.
  • If you're a security researcher, join Patchstack Alliance to report vulnerabilities & earn rewards.

The latest in Security Advisories

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.
crossmenu