8 Aug 2023

Update to WordPress’ Own Plugin With 300,000+ Installs Introduces Insecure Code

In addition to tens of thousands of third-party plugins for WordPress, WordPress itself is the developer of plugins. Last year we spotted a very exploitable vulnerability being introduced in to one of those, which involved a failure to implement basic security. That was introduced in to the plugin by an employee of the head of WordPress. You would hope that was an aberration and that WordPress would be implementing best practices for developing plugins. That doesn’t appear to be the case based on security issues just introduced in to one of those plugins, Health Check & Troubleshooting, which has 300,000+ installs.

The GitHub project for the plugin has this information on “reporting security issues“:

The Site Health team and WordPress community take security bugs seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.

To report a security issue, please visit the WordPress HackerOne program.

What they are linking to is a program for reporting vulnerabilities. Not all security issues are vulnerabilities, which is a problem, as they didn’t provide any instructions on how to report lesser issues. (Handling things through HackerOne or a similar program have other problems as well.)

The linked page makes this claim about software receiving “multiple levels of peer-review and testing”:

WordPress powers 40% of the Web, so changes must undergo multiple levels of peer-review and testing, to make sure that they don’t break millions of websites when they’re installed automatically.

It seems like that refers to the WordPress software itself, and not other software. That certainly doesn’t appear to be happening with this plugin. To get to that, first let’s look at the security issues we ran across in the plugin.

Version 1.7.0 of the plugin was released on Sunday. As at least one of our customers is using the plugin, it got run through several of our automated monitoring systems that flagged the update as possibly containing changes we should review.

Manually checking the code, we found a couple of security issues had been introduced in the new version.

A new function to enable or disabled beta features, toggle_beta_features(), which is located in the file /HealthCheck/Tools/class-health-check-beta-features.php, lacks a needed capabilities check to limit who can access it (it is registered to be AJAX accessible to anyone logged in to WordPress):

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public function toggle_beta_features() {
	if ( ! isset( $_GET['health-check-beta-features'] ) ) {
		return;
	}
 
	if ( ! isset( $_GET['_wpnonce'] ) ) {
		return;
	}
 
	if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'health-check-beta-features' ) ) {
		return;
	}
 
	if ( 'enable' === $_GET['health-check-beta-features'] ) {
		update_option( 'health-check-beta-features', true );

There is a nonce check that normally would do the equivalent of that, but it isn’t intended for that purpose.

The new function delete_screenshot() in the file /HealthCheck/class-health-check-screenshots.php allows anything stored as a post to be deleted:

57
58
59
60
61
62
63
64
65
66
67
public function delete_screenshot() {
	if ( ! is_admin() || ! isset( $_GET['health-check-delete-screenshot'] ) || ! $this->user_can_screenshot() ) {
		return;
	}
 
	// Validate nonces.
	if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'health-check-delete-screenshot' ) ) {
		return;
	}
 
	wp_delete_post( $_GET['health-check-delete-screenshot'], true );

That means it can be used to delete what it is intended to, the plugin’s screenshots, but also WordPress posts, but pages, and various data from plugins. Normally only Administrators would have access to that. As they can already delete those things, that wouldn’t normally be a vulnerability, but it still should be properly secured.

Limiting what could be deleted could be done in several ways. Among them, there could be a nonce check specific for the item intended to be deleted to be checked for. Or a check to make sure the post to be deleted is of the intended type. Or a combination of those.

That code was added to the GitHub project for the plugin on Sunday as well. There is only one person shown as being involved in that. So there doesn’t appear to be any peer-review going on there, nor was there almost any chance for anyone to have done that.

For whatever reason, the commit that included the addition of those two functions wasn’t run through coding checks that are there for this plugin:

That was despite a second commit being checked. And then a third commit being made to address an issue flagged when the second commit was checked.

We reported those security issues on Monday, so hopefully they will be quickly resolved.

Better Practices Needed

It’s hard to fault third-party developers for not properly securing their own plugins, when WordPress isn’t accomplishing that either. Having a peer-review of code changes would be a good start to improving them. That looks like it might be a problem with this plugin, as the commits being made suggest that the plugin is almost entirely being developed by one person. Beyond expanding the developer base of that plugin to address that, perhaps WordPress could have a team that uses its own plugins to better understand why security issues are occurring in plugins and come up with better practices to avoid them.

Unless and until that happens, actually having outside security reviews of WordPress plugins done (almost none happen now), would help to avoid security issues and vulnerabilities from impacting so many WordPress websites.


Plugin Security Scorecard Grade for Health Check & Troubleshooting

Checked on July 31, 2024
B+

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

Leave a Reply

Your email address will not be published.