9 May 2022

WordPress Plugin Developer Security Advisory: mndpsingh287

One of the little understood realities of security issues with WordPress plugins is that insecurity of WordPress plugins is not evenly spread across them. Instead, many developers are properly securing their plugins and others get them properly secured when alerted they haven’t done that, while others either are unable or unwilling to properly secure their plugins. That includes situations where developers have introduced new serious vulnerabilities that are substantially similar to vulnerabilities that they know have been exploited in their plugins.

In situations where we become aware of developers who have shown that inability or unwillingness to properly secure their plugin, we are releasing advisories to warn customers of our service and the wider WordPress community of the risk of utilizing those developers’ plugins. In addition to checking those posts on our website for information on those advisory, we provide access to the information in several other forms. That includes through the companion plugin for our service, even when not using the service, as well as through a web browser extension and through separate data accessible from our website.

mndpsingh287

Two types of WordPress plugins that have heightened security risk are file managers and backup plugins. The plugin File Manager (WP File Manager) combines both, but the developer mndpsingh287 has continued to fail to implement basic security in the plugin, even when specifically notified that is it missing (a problem that extends to at least another of their plugins). That has led to vulnerabilities you would expect wide spread exploitation attempts against and, in line with that, widespread attempts to exploit those. Despite that, the plugin has 900,000+ active installs according to WordPress.

We recently having been seeing many requests on our website and third-party data, for a file from the plugin :

/wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php

While that would appear to be rather belated attempts to exploit a vulnerability fixed in 2020, we went to check on the plugin after seeing that and we found it is still lacking basic security.

Known Lack of a Capabilities Check Since 2017

When using the plugin’s file manager, requests to take actions and see the results of those actions are handled through AJAX requests. Most of that is that handled by the function mk_file_folder_manager_action_callback() in the file /file_folder_manager.php. That function is registered to be accessible by anyone logged in to WordPress:

27
add_action('wp_ajax_mk_file_folder_manager', array(&$this, 'mk_file_folder_manager_action_callback'));

As it is accessible to anyone logged in to WordPress, there should be a capabilities check to limit access to only users intended to access that, in the function. The admin page for the file manager requires the “mange_options” capability, which normally only Administrators have:

360
361
362
363
364
365
366
367
add_menu_page(
__('WP File Manager', 'wp-file-manager'),
__('WP File Manager', 'wp-file-manager'),
'manage_options',
'wp_file_manager',
array(&$this, 'ffm_settings_callback'),
plugins_url('images/wp_file_manager.svg', __FILE__)
);

The function lacks a capabilities check, and the only restriction in place is a nonce check (which is intended to prevent cross-site request forgery (CSRF)):

1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
public function mk_file_folder_manager_action_callback()
{
	$path = ABSPATH;
	$settings = get_option('wp_file_manager_settings');
	if (isset($settings['public_path']) && !empty($settings['public_path'])) {
		$path = $settings['public_path'];
	}
	$mk_restrictions = array();
	$mk_restrictions[] = array(
						  'pattern' => '/.tmb/',
						   'read' => false,
						   'write' => false,
						   'hidden' => true,
						   'locked' => false,
						);
	$mk_restrictions[] = array(
						  'pattern' => '/.quarantine/',
						   'read' => false,
						   'write' => false,
						   'hidden' => true,
						   'locked' => false,
						);
	$nonce = sanitize_text_field($_REQUEST['_wpnonce']);
	if (wp_verify_nonce($nonce, 'wp-file-manager')) {

While in normal circumstances, as long the nonce used in the nonce check is only provided to the intended users, then that would restrict access by lower-level users. But it isn’t intended for that role, as the WordPress documentation makes clear:

Nonces should never be relied on for authentication, authorization, or access control. Protect your functions using current_user_can(), and always assume nonces can be compromised.

The lack of a capabilities check can become a big problem if the nonce isn’t restricted (as we recently found with the plugin 5+ million active install plugin Elementor). It also could become a problem if a hacker could exploit a vulnerability to generate a valid nonce.

While reviewing things while preparing this advisory, we found we had notified the developer of that specific missing capabilities check in June 2017. That isn’t the only time we have contacted them about unaddressed issues without even getting a response.

Oddly Handled Security

The latest version of the plugin, 7.1.5, which was released less than a month ago, had the following changelog entries:

  • Updated translations
  • Fixed zip extract issue
  • Minor other bug fixes

What isn’t mentioned there is that there was a security change being made. It was one that wasn’t handled correctly.

As of the previous version, the plugin didn’t restrict who had access to its function for handling downloading a backup file made through the plugin, which runs through WordPress’ REST API:

59
60
61
62
63
register_rest_route( 'v1', '/fm/backupall/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z]+)', array(
	'methods' => 'GET',
	'callback' => array( $this, 'fm_download_backup_all' ),
	'permission_callback' => '__return_true',
));

The permission_callback of that should have been set to limit that. A secret key is also needed to download a backup, so the lack of that capabilities check alone wouldn’t have allowed downloading backups, but another vulnerability could have gotten the secret key and then backups could be downloaded.

In the new version, the developer still hasn’t utilized the permission_callback as they should, instead adding a capabilities check around the function:

51
52
53
54
55
56
57
58
59
60
61
62
63
if(is_user_logged_in() && current_user_can('manage_options')){
	register_rest_route( 'v1', '/fm/backup/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)', array(
		'methods' => 'GET',
		'callback' => array( $this, 'fm_download_backup' ),
		'permission_callback' => '__return_true',
	));
 
	register_rest_route( 'v1', '/fm/backupall/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z0-9-=]+)/(?P[a-zA-Z]+)', array(
		'methods' => 'GET',
		'callback' => array( $this, 'fm_download_backup_all' ),
		'permission_callback' => '__return_true',
	));
}

Another much less serious issue, though one that indicates the developer doesn’t understand what they are doing, is their misuse of is_admin(). That function will check if someone is accessing the admin area of WordPress, not as is often thought, checking if someone is logged in as an Administrator.

The plugin uses multiple times in an odd way. As an example of that, here is its usage in the function ffm_settings_callback():

780
781
782
783
784
785
public function ffm_settings_callback()
{
	if (is_admin()):
	 include 'lib/wpfilemanager.php';
	endif;
}

The only place that function is called is to create the plugin’s main admin page:

360
361
362
363
364
365
366
367
add_menu_page(
__('WP File Manager', 'wp-file-manager'),
__('WP File Manager', 'wp-file-manager'),
'manage_options',
'wp_file_manager',
array(&$this, 'ffm_settings_callback'),
plugins_url('images/wp_file_manager.svg', __FILE__)
);

As the function is only being called when accessing the admin area, that will be always true. It is unclear if the developer was trying to add protection in case it was accessed separately, but is_admin() wouldn’t be the right thing to do that.

Avoid Their Plugins

Recommending avoiding plugins by this developer is a pretty easy call based on their track record and the current state of this plugin.


Plugin Security Scorecard Grade for WP File Manager

Checked on February 21, 2025
F

See issues causing the plugin to get less than A+ grade

Leave a Reply

Your email address will not be published.